package com.yanqu.road.server.manager.union;

import com.alibaba.fastjson.JSON;
import com.yanqu.data.analytics.helper.DataBuilder;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.cross.*;
import com.yanqu.road.entity.player.CrossUserBaseInfo;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.UnionRank;
import com.yanqu.road.entity.rank.UnionValueRank;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.union.*;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUnion;
import com.yanqu.road.entity.union.cross.*;
import com.yanqu.road.entity.union.parergon.UnionParergon;
import com.yanqu.road.entity.union.parergon.UnionParergonOperateResult;
import com.yanqu.road.entity.union.parergon.UnionParergonPlayer;
import com.yanqu.road.logic.bussiness.union.cross.CrossUnionBussiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.cross.CrossGroupMonthRankListModel;
import com.yanqu.road.logic.pb.CrossUnionPb;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.logic.redis.RedisManger;
import com.yanqu.road.pb.assistant.AssistantProto;
import com.yanqu.road.pb.server.ServerProto;
import com.yanqu.road.pb.union.UnionProto;
import com.yanqu.road.pb.union.cross.CrossUnionHonorsProto;
import com.yanqu.road.pb.union.cross.CrossUnionProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.CrossDataAnalyticsMgr;
import com.yanqu.road.server.manager.config.CrossSystemLoopMgr;
import com.yanqu.road.server.manager.config.GoodsMgr;
import com.yanqu.road.server.manager.config.PatronsMgr;
import com.yanqu.road.server.manager.group.SystemGroupHelper;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.union.activitygroup.Cross3UnionActivityGroupMgr;
import com.yanqu.road.server.manager.union.activitygroup.UnionActivityGroupLockMgr;
import com.yanqu.road.server.manager.rank.CrossGroupUserMonthAbilityRankMgr;
import com.yanqu.road.server.manager.union.huaben.CrossUnionHuaBenMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manager.user.CrossUserNotifyMgr;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.CrossUnionServerGroupMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.plugin.ManagerReloadListener;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.utils.*;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.executor.GeneralTask;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.util.ConcurrentHashSet;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class CrossUnionMgr extends TempMgr {

    private static Logger logger = LogManager.getLogger(CrossUnionMgr.class.getName());

    private static RandomHelper random = new RandomHelper();

    private static Map<String, CrossUnionInfo> unionInfoMap;
    //key=serverId
    private static Map<Long, List<CrossUnionInfo>> serverUnionListMap = new ConcurrentHashMap<>();

    private static Map<String, CrossUnionInfo> deleteUnionInfoMap;

    private static Map<String, Map<Long, CrossUnionMember>> unionMemberMap;

    private static Map<Long, CrossUnionMember> deleteUnionMemberMap;

    private static Map<Long, CrossUnionChamberPatrons> chamberPatronsMap;

    private static AtomicLong maxUnionAliasId;

    protected static Map<String, Map<Integer, CrossUnionFlag>> unionFlagMap;

    private static Map<Long, CrossUnionMember> allUnionMemberMap;

    private static Set<String> syncMaxAbilityUnionSet = new HashSet<>();

    @Override
    public boolean init() throws Exception {
        CrossUserNotifyMgr.addSyncListener(new UnionMemberUserBaseSyncListener());
        CrossUnionServerGroupMgr.addReloadListener(new ManagerReloadListener() {
            @Override
            public void notifyReload() {
                SystemGroupHelper.notifyServerReload(eSystemId.Union.getValue());
            }
        });
        return reload();
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean save() {

        List<CrossUnionInfo> unionInfoList = new ArrayList<>(unionInfoMap.values());
        for (CrossUnionInfo unionInfo : unionInfoList) {
            if (unionInfo.isInsertOption()) {
                CrossUnionBussiness.addUnionInfo(unionInfo);
            } else if (unionInfo.isUpdateOption()) {
                CrossUnionBussiness.updateUnionInfo(unionInfo);
            }
        }
        for (CrossUnionMember unionMember : allUnionMemberMap.values()) {
            if (unionMember.isInsertOption()) {
                CrossUnionBussiness.addUnionMember(unionMember);
            } else if (unionMember.isUpdateOption()) {
                CrossUnionBussiness.updateUnionMember(unionMember);
            }
        }
        for (Map<Integer, CrossUnionFlag> flagMap : new ArrayList<>(unionFlagMap.values())) {
            for (CrossUnionFlag flag : new ArrayList<>(flagMap.values())) {
                if (flag.isInsertOption()) {
                    CrossUnionBussiness.addUnionFlag(flag);
                } else if (flag.isUpdateOption()) {
                    CrossUnionBussiness.updateUnionFlag(flag);
                }
            }
        }
        for (Map.Entry<Long, CrossUnionChamberPatrons> entry : chamberPatronsMap.entrySet()) {
            CrossUnionChamberPatrons chamberPatrons = entry.getValue();
            if(chamberPatrons.isInsertOption()){
                CrossUnionBussiness.addCrossUnionChamberPatrons(chamberPatrons);
            }else if(chamberPatrons.isUpdateOption()){
                CrossUnionBussiness.updateCrossUnionChamberPatrons(chamberPatrons);
            }
        }
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        initMaxUnionAliasId();
        Map<String, CrossUnionInfo> tempUnionInfoMap = new ConcurrentHashMap<>();
        Map<String, CrossUnionInfo> tempDeleteUnionInfoMap = new ConcurrentHashMap<>();
        CrossUnionBussiness.getUnionInfoMap(tempUnionInfoMap, tempDeleteUnionInfoMap);

        Map<Long, List<CrossUnionInfo>> tempServerUnionListMap = new ConcurrentHashMap<>();
        for (CrossUnionInfo crossUnionInfo : tempUnionInfoMap.values()) {
            List<CrossUnionInfo> unionInfoList = tempServerUnionListMap.get(crossUnionInfo.getServerId());
            if (unionInfoList == null) {
                unionInfoList = new ArrayList<>();
                tempServerUnionListMap.put(crossUnionInfo.getServerId(), unionInfoList);
            }
            unionInfoList.add(crossUnionInfo);
        }

        unionInfoMap = tempUnionInfoMap;
        deleteUnionInfoMap = tempDeleteUnionInfoMap;
        serverUnionListMap = tempServerUnionListMap;

        Map<String, Map<Long, CrossUnionMember>> tempUnionMemberMap = new ConcurrentHashMap<>();
        Map<Long, CrossUnionMember> tempDeleteMemberMap = new ConcurrentHashMap<>();
        allUnionMemberMap = CrossUnionBussiness.getUnionMemberMap(tempUnionMemberMap, tempDeleteMemberMap);
        Map<Long, CrossUnionChamberPatrons> tempChamberPatronsMap = CrossUnionBussiness.getCrossChamberPatrons();
        initMemberChamber(allUnionMemberMap, tempChamberPatronsMap);
        unionMemberMap = tempUnionMemberMap;
        deleteUnionMemberMap = tempDeleteMemberMap;
        unionFlagMap = CrossUnionBussiness.getAllUnionFlag();
        chamberPatronsMap = tempChamberPatronsMap;
        //校验商会有效性
        checkUnionValid();
        resetOneDay();

        //更新初始商会最高赚钱
        for (CrossUnionInfo unionInfo : unionInfoMap.values()) {
            updateUnionTotalMaxAbility(unionInfo.getUnionUid());
        }

        return true;
    }

    /**
     * 议事厅门客与member关联
     */
    private void initMemberChamber(Map<Long, CrossUnionMember> unionMemberMap, Map<Long, CrossUnionChamberPatrons> tempChamberPatronsMap) {
        for (CrossUnionMember data : unionMemberMap.values()) {
            if(tempChamberPatronsMap.containsKey(data.getUserId())){
                data.setChamberPatrons(tempChamberPatronsMap.get(data.getUserId()));
            }
        }
    }

    /**
     * 初始化读取当前最大商会别名编号
     */
    private static void initMaxUnionAliasId() {
        long tempMaxUnionAliasId = CrossUnionBussiness.getMaxUnionAliasId();
        long start = 10000000L;
        if (0 == tempMaxUnionAliasId) {
            int channelId = ConfigHelper.getInt("channelId");
            maxUnionAliasId = new AtomicLong(start * channelId);
        } else {
            long min = start * 100;
            if(tempMaxUnionAliasId < min){
                tempMaxUnionAliasId = tempMaxUnionAliasId + min;
            }
            maxUnionAliasId = new AtomicLong(tempMaxUnionAliasId);
        }
    }

    /**
     * 商会数据校验
     */
    private static void checkUnionValid() {
        for (CrossUnionInfo unionInfo : unionInfoMap.values()) {
            Map<Long, CrossUnionMember> memberMap = unionMemberMap.get(unionInfo.getUnionUid());
            if (null == memberMap) {//没有成员
                unionInfo.setDelete(true);
            }
        }
        List<String> unionUidList = new ArrayList<>();
        for (Map.Entry<String, Map<Long, CrossUnionMember>> dataEntry : unionMemberMap.entrySet()) {
            if (!unionInfoMap.containsKey(dataEntry.getKey())) {
                unionUidList.add(dataEntry.getKey());
            }
        }
        for (String unionUid : unionUidList) {
            Map<Long, CrossUnionMember> memberMap = unionMemberMap.remove(unionUid);
            if (null != memberMap) {
                for (CrossUnionMember member : memberMap.values()) {
                    member.setUnionUid("");
                    deleteUnionMemberMap.put(member.getUserId(), member);
                }
            }
        }
    }

    /**
     * 每日重置
     */
    public static void resetOneDay() {
        for (CrossUnionInfo unionInfo : unionInfoMap.values()) {
            if (unionInfo.isDelete()) {
                continue;
            }
            resetUnionDailyData(unionInfo);
            Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionInfo.getUnionUid());
            if (null != memberMap) {
                for (CrossUnionMember member : memberMap.values()) {
                    resetMemberDailyData(member);
                }
            }
        }
    }

    /**
     * 创建商会
     */
    public static int createUnion(CrossUserBaseInfo player, String unionName, boolean isAllowRandomJoin, String outNotice, String weChatCode,
                                  String qqCode, String innerNotice, int unionFlag) {
        CrossUnionInfo unionInfo;
        long serverId = player.getUserBaseInfo().getServerId();
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            CrossUnionMember unionMember = getUnionMemberByUserId(player.getUserId());
            if(null != unionMember) {
                if(!StringUtils.isNullOrEmpty(unionMember.getUnionUid())){
                    return GameErrorCode.E_UNION_HAS_JOIN_UNION;
                }
                long nowTime = System.currentTimeMillis() / 1000;
                if(nowTime - unionMember.getQuitTime() < GameConfig.UNION_NEXT_JOIN_NEED_TIME){
                    return GameErrorCode.E_UNION_NEXT_JOIN_TIME_NO_ENOUGH;
                }
            }


            int channelId = ConfigHelper.getInt("channelId");
            String unionUid = UUIDHelper.randomUUID(String.valueOf(channelId));
            int ret = CrossUnionConfigMgr.checkUnionName(unionName, unionUid);
            if(0 != ret){
                return ret;
            }
            ret = CrossUnionConfigMgr.checkOutNotice(outNotice, unionUid);
            if(0 != ret){
                return ret;
            }
            ret = CrossUnionConfigMgr.checkInnerNotice(innerNotice);
            if(0 != ret){
                return ret;
            }

            //商会重名检测
            if (checkUnionNameSame(unionName)) {
                return GameErrorCode.E_UNION_NAME_SAME;
            }
            unionInfo = initUnionInfo(player, unionName, isAllowRandomJoin, outNotice, weChatCode, qqCode, innerNotice, unionFlag, unionUid);

            unionMember = createUnionMember(unionInfo, player, eUnionPosition.Master.getValue());

            unionInfo.setGradeAmountMap(getMemberRankGradeMap(unionInfo));

            CrossUnionNoticeMgr.checkUnionNotice(unionInfo.getUnionUid());

            //副业相关初始化及下发
            CrossUnionParergonMgr.getParergon(unionUid);
            CrossUnionParergonMgr.sycnUserAllParergonData(player);

            sendUnionChangeBroadcast(eUnionSyncType.CreateUnion.getValue(), unionInfo, player, null, player.getUserId());

            CrossUnionProto.UnionCreateCrossRespMsg.Builder respMsg = CrossUnionProto.UnionCreateCrossRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setFirstCreate(unionMember.getQuitTime() <= 0);
            respMsg.setUnionUid(unionInfo.getUnionUid());
            MessageHelper.sendPacket(unionMember.getServerId(), unionMember.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_UNION_CREATE_FROM_CROSS, respMsg));

            // 更新下商会活动分组
            UnionActivityGroupLockMgr.getThreadTaskManger().addTask(0, new GeneralTask() {
                @Override
                public void doRun() {
                    UnionActivityGroupLockMgr.onUnionChange(unionUid);
                    UnionActivityGroupLockMgr.onUserJoinUnion(unionUid, player.getUserId());
                }
            });
        }
        return 0;
    }

    /**
     * 初始商会数据
     */
    private static CrossUnionInfo initUnionInfo(CrossUserBaseInfo player, String unionName, boolean isAllowRandomJoin, String outNotice,
                                           String weChatCode, String qqCode, String innerNotice, int unionFlag, String unionUid) {
        UserBaseInfo userInfo = player.getUserBaseInfo();
        long nowTime = System.currentTimeMillis() / 1000;
        CrossUnionInfo unionInfo = new CrossUnionInfo(unionUid);
        unionInfo.setUnionName(unionName);
        unionInfo.setUnionFlag(unionFlag);
        unionInfo.setAllowRandomJoin(isAllowRandomJoin);
        unionInfo.setWechatCode(weChatCode);
        unionInfo.setQqCode(qqCode);
        unionInfo.setOutNotice(outNotice);
        unionInfo.setCreateTime(nowTime);
        unionInfo.setDelete(false);
        unionInfo.setExperience(0);
        unionInfo.setInnerNotice(innerNotice);
        unionInfo.setMasterUserId(player.getUserId());
        unionInfo.setMasterNickName(userInfo.getNickName());
        unionInfo.setVipExp(userInfo.getVipExp());
        unionInfo.setMasterJoinTime(nowTime);
        unionInfo.setMemberCount(1);
        unionInfo.setTotalEarnSpeed(BigInteger.ZERO);
        unionInfo.setConstructUserIdList(new ArrayList<>());
        unionInfo.setModifyTime(0);
        unionInfo.setWealth(0);
        unionInfo.setUnionFightRewardMark(0);
        unionInfo.setFlagModifyTime(nowTime);
        unionInfo.setUnionAliasId(getNextUnionAliasId());
        unionInfo.setDecoration(userInfo.getDecoration());
        unionInfo.setDayJoinNum(0);
        unionInfo.setApplyTitleLimit(0);
        unionInfo.setServerId(player.getUserBaseInfo().getServerId());
        unionInfo.setJoinGradeLimit(getNewJoinLimitMap(unionInfo));

        unionInfo.setInsertOption();

        unionInfoMap.put(unionInfo.getUnionUid(), unionInfo);

        synchronized (CrossUnionLockerMgr.getServerLocker(unionInfo.getServerId())) {
            List<CrossUnionInfo> unionInfoList = serverUnionListMap.get(unionInfo.getServerId());
            if (unionInfoList == null) {
                unionInfoList = new ArrayList<>();
                serverUnionListMap.put(unionInfo.getServerId(), unionInfoList);
            }
            unionInfoList.add(unionInfo);
        }
        return unionInfo;
    }

    /**
     * 随机加入
     * @param player
     * @param excludeUnionList  排除加入的联盟id 集合
     * @return
     */
    public static int randomJoin(CrossUserBaseInfo player, List<String> excludeUnionList) {
        long serverId = player.getUserBaseInfo().getServerId();
        long userId = player.getUserId();

        int crossServerCount = CrossUnionServerGroupMgr.getGroupServerCountByServerId(serverId);
        if(crossServerCount >= GameConfig.UNION_PLAYER_OPEN_COND_AREA_NUM) {//达到商会评定要求
            if (!CrossGroupUserMonthAbilityRankMgr.isServerGroupOver(serverId)) {
                return GameErrorCode.E_UNION_CAN_NOT_APPLY_JOIN_MONTH_ABILITY_RANK_CHANGE;
            }
        }

        List<CrossUnionInfo> listInSameGroup = getUnionListInSameGroup(serverId);
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            String ownUnionUid = player.getUserBaseInfo().getUnionUid();
            CrossUnionMember unionMember = CrossUnionMgr.getUnionMemberByUserId(player.getUserId());
            if (unionMember != null) {//身上的商会id以member为准
                ownUnionUid = unionMember.getUnionUid();
            } else {
                ownUnionUid = "";
            }
            if(!StringUtils.isNullOrEmpty(ownUnionUid)){
                return GameErrorCode.E_UNION_HAS_JOIN_UNION;
            }
            List<CrossUnionInfo> tempUnionList = new ArrayList<>();
            int maxCount = 0;
            for (CrossUnionInfo unionInfo : listInSameGroup) {
                if (unionInfo.getServerId() != player.getUserBaseInfo().getServerId() && !unionInfo.isCross()) {
                    continue;
                }
                if (!unionInfo.isDelete() && unionInfo.isAllowRandomJoin() &&
                        player.getUserBaseInfo().getTitleId() >= unionInfo.getApplyTitleLimit() &&
                        !excludeUnionList.contains(unionInfo.getUnionUid()) &&
                        canJoinUnionByAbilityGrade(unionInfo, serverId, userId)) {
                    int memberCount = getUnionMemberCount(unionInfo.getUnionUid());
                    if (memberCount < CrossUnionConfigMgr.getMaxMemberCount(unionInfo.getExperience(), unionInfo.isCross(), crossServerCount)
                            && !isDayJoinNumLimit(unionInfo)
                    ) {
                        if (memberCount > maxCount) {
                            maxCount = memberCount;
                            tempUnionList.clear();
                            tempUnionList.add(unionInfo);
                        } else if (memberCount == maxCount) {
                            tempUnionList.add(unionInfo);
                        }
                    }
                }
            }

            if (tempUnionList.size() > 0) {
                int size = random.next(0, tempUnionList.size());
                CrossUnionInfo unionInfo = tempUnionList.get(size);
                int ret = addUnionMember(player, unionInfo.getUnionUid(), player.getUserId());
                if(ret != 0){
                    return ret;
                }

                CrossUnionParergonMgr.sycnUserAllParergonData(player);

                sendUnionChangeBroadcast(eUnionSyncType.JoinUnion.getValue(), unionInfo, player, null, player.getUserId());

                List<CrossUnionMember> memberList = new ArrayList<>();
                unionMember = CrossUnionMgr.getUnionMember(unionInfo.getUnionUid(), player.getUserId());
                if(unionMember != null) {
                    memberList.add(unionMember);
                    CrossUnionNotifyMgr.notifyListener(eUnionSyncType.JoinUnion.getValue(), player.getUserId(), unionInfo, memberList);
                }
                return 0;
            } else {
                return GameErrorCode.E_UNION_NO_RANDOM_JOIN;
            }
        }
    }

    public static List<CrossUnionInfo> getUnionListByServerId(long serverId) {
        List<CrossUnionInfo> unionInfoList = new ArrayList<>();
        synchronized (CrossUnionLockerMgr.getServerLocker(serverId)) {
            unionInfoList.addAll(serverUnionListMap.getOrDefault(serverId, new ArrayList<>()));
        }
        return unionInfoList;
    }


    public static List<CrossUnionInfo> getUnionListInSameGroup(long serverId){
        List<CrossUnionInfo> list = new ArrayList<>();
        int groupId = CrossUnionServerGroupMgr.getGroupIdByServerId(serverId);
        Set<Long> serverSet = CrossUnionServerGroupMgr.getGroupServer(groupId);

        for (Long takeServerId : serverSet) {
            List<CrossUnionInfo> unionInfoList = getUnionListByServerId(takeServerId);
            for (CrossUnionInfo unionInfo : unionInfoList) {
                if (unionInfo.isDelete()) {
                    continue;
                }
                list.add(unionInfo);
            }
        }
        return list;
    }

    /**
     * 已删除会过滤掉
     * @param serverIdSet
     * @return
     */
    public static List<CrossUnionInfo> getUnionListByServerList(Set<Long> serverIdSet) {
        List<CrossUnionInfo> list = new ArrayList<>();
        for (Long serverId : serverIdSet) {
            List<CrossUnionInfo> unionInfoList = getUnionListByServerId(serverId);
            for (CrossUnionInfo unionInfo : unionInfoList) {
                if (unionInfo.isDelete()) {
                    continue;
                }
                list.add(unionInfo);
            }
        }
        return list;
    }

    /**
     * 已删除会过滤掉
     * @param serverIdList
     * @return
     */
    public static List<CrossUnionInfo> getUnionListByServerList(List<Long> serverIdList) {
        List<CrossUnionInfo> list = new ArrayList<>();
        for (Long serverId : serverIdList) {
            List<CrossUnionInfo> unionInfoList = getUnionListByServerId(serverId);
            for (CrossUnionInfo unionInfo : unionInfoList) {
                if (unionInfo.isDelete()) {
                    continue;
                }
                list.add(unionInfo);
            }
        }
        return list;
    }


    public static int addUnionMember(CrossUserBaseInfo roleUser, String unionUid, long joinUserId) {

        CrossUserBaseInfo joinPlayer;
        CrossUnionInfo unionInfo = getUnionInfo(unionUid);
        if (null == unionInfo) {
            return GameErrorCode.E_UNION_NO_FOUND;
        }
        long serverId = roleUser.getUserBaseInfo().getServerId();

        int crossServerCount = CrossUnionServerGroupMgr.getGroupServerCountByServerId(unionInfo.getServerId());
        if(crossServerCount >= GameConfig.UNION_PLAYER_OPEN_COND_AREA_NUM) {//达到商会评定要求
            if (!CrossGroupUserMonthAbilityRankMgr.isServerGroupOver(serverId)) {
                return GameErrorCode.E_UNION_CAN_NOT_APPLY_JOIN_MONTH_ABILITY_RANK_CHANGE;
            }
        }

        joinPlayer = CrossUserMgr.getCrossUserBaseInfo(joinUserId);

        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            if(crossServerCount >= GameConfig.UNION_PLAYER_OPEN_COND_AREA_NUM) {//达到商会评定要求
                if (!CrossUnionMgr.canJoinUnionByAbilityGrade(unionInfo, serverId, joinUserId)) {
                    return GameErrorCode.E_UNION_CAN_NOT_APPLY_JOIN_RANKGRADE_FULL;
                }
            }
            int currentCount = getUnionMemberCount(unionUid);
            if (currentCount >= CrossUnionConfigMgr.getMaxMemberCount(unionInfo.getExperience(), unionInfo.isCross(), crossServerCount)) {
                return GameErrorCode.E_UNION_MEMBER_FULL;
            }
            if (isDayJoinNumLimit(unionInfo)) {
                return GameErrorCode.E_UNION_PER_DAY_JOIN_NUM_LIMIT;
            }
            UnionMember unionMember = CrossUnionMgr.getUnionMemberByUserId(joinUserId);
            if (null != unionMember) {
                if(!StringUtils.isNullOrEmpty(unionMember.getUnionUid())){
                    return GameErrorCode.E_UNION_HAS_JOIN_UNION;
                }
                if (unionMember.getKickTime() >= (GameConfig.UNION_NEXT_JOIN_NEED_TIME >= 10 * DateHelper.MINUTE_SECONDS
                        ? (unionMember.getQuitTime() + GameConfig.UNION_NEXT_JOIN_NEED_TIME - 10 * DateHelper.MINUTE_SECONDS)
                        : unionMember.getQuitTime())) {
                    //最后是被踢，不一定需要冷却时间
                    if(unionMember.getKickTime() - unionMember.getJoinTime() > GameConfig.UNION_KICK_PROTECT_LIMIT){
                        long nowTime = System.currentTimeMillis() / 1000;
                        //退出都需要10分钟冷却
                        if (nowTime - unionMember.getKickTime() < 10 * DateHelper.MINUTE_SECONDS) {
                            return GameErrorCode.E_UNION_NEXT_JOIN_TIME_NO_ENOUGH;
                        }
                    }
                }else {
                    long nowTime = System.currentTimeMillis() / 1000;
                    if (nowTime - unionMember.getQuitTime() < GameConfig.UNION_NEXT_JOIN_NEED_TIME) {
                        return GameErrorCode.E_UNION_NEXT_JOIN_TIME_NO_ENOUGH;
                    }
                }
            }
            CrossUnionMember member = createUnionMember(unionInfo, joinPlayer, eUnionPosition.Member.getValue());
            member.setJoinTime(System.currentTimeMillis() / 1000);
            unionInfo.setMemberCount(getUnionMemberCount(unionUid));
            unionInfo.setDayJoinNum(1 + unionInfo.getDayJoinNum());
            calcUnionEarnSpeed(unionInfo);
        }
        //商会日志
        CrossUnionNoticeMgr.addNotice(roleUser, unionUid, eUnionNoticeType.JoinUnion.getValue(), joinPlayer.getUserBaseInfo().getNickName());

        //加入
        CrossAutoLogMgr.add(new LogUnionMemberChange(joinUserId, "", unionUid));
        // 更新下商会活动分组
        UnionActivityGroupLockMgr.getThreadTaskManger().addTask(0, new GeneralTask() {
            @Override
            public void doRun() {
                UnionActivityGroupLockMgr.onUnionChange(unionUid);
                UnionActivityGroupLockMgr.onUserJoinUnion(unionUid, joinUserId);
            }
        });

        return 0;
    }

    private static CrossUnionMember createUnionMember(CrossUnionInfo unionInfo, CrossUserBaseInfo userInfo, int position) {
        CrossUnionMember unionMember = getUnionMemberByUserId(userInfo.getUserId());
        if (null == unionMember) {
            unionMember = new CrossUnionMember();
            unionMember.setUnionUid(unionInfo.getUnionUid());
            unionMember.setUserId(userInfo.getUserId());
            unionMember.setContribution(0);
            unionMember.setTotalContribution(0);
            unionMember.setDonateTimes(0);
            unionMember.setServerId(userInfo.getUserBaseInfo().getServerId());
            unionMember.setMonthAbilityRank(CrossGroupUserMonthAbilityRankMgr.getUserRank(unionMember.getServerId(), unionMember.getUserId()));
            unionMember.setInsertOption();
        } else {
            unionMember.setUnionUid(unionInfo.getUnionUid());
            unionMember.setUserId(userInfo.getUserId());
            removeMemberFromDeleteMap(userInfo.getUserId());
            long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000;
            if (unionMember.getModifyTime() < zeroTime) {
                unionMember.setUnionConstructMap(new ConcurrentHashMap<>());
                unionMember.setConstructRewardIndexList(new ArrayList<>());
                unionMember.setDonateTimes(0);
            }
            unionMember.setServerId(userInfo.getUserBaseInfo().getServerId());
        }
        if (unionMember.getQuitTime() <= 0) {
            //sendFirstJoinReward(userInfo); //区服处理
        }
        unionMember.setNoticeReadState(eUnionNoticeReadState.Default.getValue());
        unionMember.setTodayContribution(0);
        unionMember.setTotalContribution(0);
        unionMember.setUserBaseInfo(userInfo.getUserBaseInfo());
        unionMember.setPosition(position);
        unionMember.setModifyTime(System.currentTimeMillis() / 1000);

        userInfo.getUserBaseInfo().setUnionUid(unionInfo.getUnionUid());
        userInfo.getUserBaseInfo().setUnionName(unionInfo.getUnionName());

        //Redis修改角色商会信息
        if(ChannelConfig.USER_INFO_USE_REDIS == 1) {
            try {
                RedisManger.getRedisUtil().setString("user_base_info:" + userInfo.getUserId(), JSON.toJSONString(userInfo.getUserBaseInfo()));
            } catch (Exception e) {
                logger.error("update user info to redis fail,userId:{},error:", userInfo.getUserId(), e);
            }
        }

        addMemberToMap(unionMember);
        calcUnionEarnSpeed(unionInfo);

        try {
            for (String unionId : StringUtils.stringToStringList(unionMember.getApplyUnionUidListString(), ",")) {
                if (!StringUtils.isNullOrEmpty(unionId)) {
                    Map<Long, UnionJoinApply> applyMap = CrossUnionJoinApplyMgr.getUnionJoinApplyMap(unionId);
                    if (applyMap != null) {
                        UnionJoinApply unionJoinApply = applyMap.get(userInfo.getUserId());
                        if (unionJoinApply != null) {
                            applyMap.remove(userInfo.getUserId());
                            unionJoinApply.setDelete(true);
                            CrossUnionJoinApplyMgr.syncJoinApply(unionId, unionJoinApply);
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        unionMember.setApplyUnionUidList(new ArrayList<>());

        return unionMember;
    }

    //cmd

    /**
     * 主动退出商会
     */
    public static int quitUnion(CrossUserBaseInfo player){

        long serverId = player.getUserBaseInfo().getServerId();
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)){
            CrossUnionMember member = getUnionMember(player.getUserBaseInfo().getUnionUid(), player.getUserId());
            if(member == null){
                return GameErrorCode.E_UNION_NO_JOIN_UNION;
            }
            CrossUnionInfo unionInfo = getUnionInfo(member.getUnionUid());
            if (null == unionInfo) {
                return GameErrorCode.E_UNION_NO_JOIN_UNION;
            }
            if (member.getUserId() == unionInfo.getMasterUserId()) {
                return GameErrorCode.E_UNION_MASTER_CAN_NO_QUIT;
            }
            removeFormUnion(player, unionInfo, member, eUnionSyncType.QuitUnion.getValue());

            //增加商会日志
            CrossUnionNoticeMgr.addNotice(player, unionInfo.getUnionUid(), eUnionNoticeType.QuitUnion.getValue(), "");

            //
            sendUnionChangeBroadcast(eUnionSyncType.QuitUnion.getValue(), unionInfo, player, null, player.getUserId());

            //退出日志
            CrossAutoLogMgr.add(new LogUnionMemberChange(player.getUserId(), unionInfo.getUnionUid(), ""));
            List<CrossUnionMember> memberList = new ArrayList<>();
            memberList.add(member);
            CrossUnionNotifyMgr.notifyListener(eUnionSyncType.QuitUnion.getValue(), player.getUserId(), unionInfo, memberList);
        }
        return 0;
    }

    /**
     * 被踢出商会
     */
    public static int kickPlayer(CrossUserBaseInfo player, long kickUserId){

        long serverId = player.getUserBaseInfo().getServerId();
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)){

            CrossUnionMember roleMember = getUnionMemberByUserId(player.getUserId());
            if(roleMember == null || StringUtils.isNullOrEmpty(roleMember.getUnionUid())){
                return GameErrorCode.E_UNION_NO_JOIN_UNION;
            }

            CrossUnionInfo unionInfo = getUnionInfo(roleMember.getUnionUid());
            if(unionInfo == null){
                return GameErrorCode.E_UNION_NO_JOIN_UNION;
            }

            CrossUnionMember removeMember = getUnionMember(unionInfo.getUnionUid(), kickUserId);
            if(removeMember == null){
                return GameErrorCode.E_UNION_NO_JOIN_UNION;
            }

            if(unionInfo.getDayKickNum() >= GameConfig.UNION_EXCHANGE_MEMBER_LIMIT){
                return GameErrorCode.E_UNION_KICK_NUM_LIMIT;
            }
            if(roleMember.getDayKickNum() >= GameConfig.UNION_EXCHANGE_MEMBER_LIMIT){
                return GameErrorCode.E_UNION_MASTER_KICK_NUM_LIMIT;
            }

            removeFormUnion(player, unionInfo, removeMember, eUnionSyncType.BeKick.getValue());

            unionInfo.setDayKickNum(1 + unionInfo.getDayKickNum());
            roleMember.setDayKickNum(1 + roleMember.getDayKickNum());

            CrossUnionNoticeMgr.addNotice(player, unionInfo.getUnionUid(), eUnionNoticeType.KickMember.getValue(), removeMember.getUserBaseInfo().getNickName());

            sendUnionChangeBroadcast(eUnionSyncType.BeKick.getValue(), unionInfo, player, null, kickUserId);

            //退出日志
            CrossAutoLogMgr.add(new LogUnionMemberChange(kickUserId, unionInfo.getUnionUid(), ""));
            List<CrossUnionMember> memberList = new ArrayList<>();
            memberList.add(removeMember);
            CrossUnionNotifyMgr.notifyListener(eUnionSyncType.BeKick.getValue(), player.getUserId(), unionInfo, memberList);

        }

        return 0;
    }

    /**
     * 解散商会,开服大于等于配置天数的进入冷静期,在冷静期的，判断时间是否结束
     */
    public static UnionProto.UnionDeleteRespMsg.Builder deleteUnion(CrossUserBaseInfo player, long nowTime, int canDeleteUnionRet) {
        UnionProto.UnionDeleteRespMsg.Builder respMsg = UnionProto.UnionDeleteRespMsg.newBuilder();
        respMsg.setRet(canDeleteUnionRet);
        respMsg.setDeleteCoolingOffTime(0);
        long serverId = player.getUserBaseInfo().getServerId();
        CrossUnionInfo unionInfo = null;
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            UnionMember member = CrossUnionMgr.getUnionMemberByUserId(player.getUserId());
            if (member == null || StringUtils.isNullOrEmpty(member.getUnionUid()) || member.getPosition() != eUnionPosition.Master.getValue()) {
                return respMsg.setRet(GameErrorCode.E_UNION_POSITION_NO_ENOUGH);
            }
            unionInfo = CrossUnionMgr.getUnionInfo(member.getUnionUid());
            if (unionInfo == null) {
                return respMsg.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
            }

            ServerInfo serverInfo = ServerListMgr.getServerInfo(unionInfo.getServerId());
            if (null != serverInfo && DateHelper.getDiffDayNum(serverInfo.getOpenTime()) >= GameConfig.UNION_DELETE_COOLING_OFF_NEED_OPEN_DAYS) {
                if (0 == unionInfo.getDeleteCoolingOffTime()) {
                    deleteInCoolingOff(player, unionInfo, serverId, nowTime);
                    return respMsg.setRet(0).setDeleteCoolingOffTime(nowTime);
                } else if (unionInfo.getDeleteCoolingOffTime() + GameConfig.UNION_DELETE_COOLING_OFF_CD > nowTime) {
                    return respMsg.setRet(GameErrorCode.E_UNION_IN_DELETE_COOLING_OFF_TIME);
                }
            }
            if (canDeleteUnionRet == 0) {
                formalDeleteUnion(player, unionInfo, serverId);
            }
        }

        return respMsg;
    }

    private static void deleteInCoolingOff(CrossUserBaseInfo player, CrossUnionInfo unionInfo, long serverId, long nowTime) {
        unionInfo.setDeleteCoolingOffTime(nowTime);
        sendUnionChangeBroadcast(eUnionSyncType.Normal.getValue(), unionInfo, null, null, 0);

        CrossAutoLogMgr.add(new LogUnionDelete(player.getUserId(), unionInfo.getUnionUid(), unionInfo.getMasterUserId(),
                unionInfo.getExperience(), unionInfo.getWealth(), eUnionDeleteState.InCoolingOffTime.getValue()));

        //增加商会日志
        CrossUnionNoticeMgr.addNotice(player, unionInfo.getUnionUid(), eUnionNoticeType.DeleteCoolingOffTime.getValue(), "");
    }

    private static void formalDeleteUnion(CrossUserBaseInfo player, CrossUnionInfo unionInfo, long serverId) {
        unionInfo.setDelete(true);
        unionInfo.setRankAddExp(0L);
        Map<Long, CrossUnionMember> deleteMap = new HashMap<>();
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionInfo.getUnionUid());
        if (memberMap != null) {
            for (CrossUnionMember unionMember : memberMap.values()) {
                deleteMap.put(unionMember.getUserId(), unionMember);
                removeFormUnion(player, unionInfo, unionMember, eUnionSyncType.DeleteUnion.getValue());
            }
        }
        sendUnionChangeBroadcast(eUnionSyncType.DeleteUnion.getValue(), unionInfo, player, deleteMap, 0);

        CrossAutoLogMgr.add(new LogUnionDelete(player.getUserId(), unionInfo.getUnionUid(), unionInfo.getMasterUserId(),
                unionInfo.getExperience(), unionInfo.getWealth(), eUnionDeleteState.FormalDelete.getValue()));

        CrossUnionNotifyMgr.notifyListener(eUnionSyncType.DeleteUnion.getValue(), player.getUserId(), unionInfo, new ArrayList<>(memberMap.values()));
    }

    /**
     * 取消解散商会
     */
    public static int cancelDeleteUnion(CrossUserBaseInfo player) {

        long serverId = player.getUserBaseInfo().getServerId();
        CrossUnionInfo unionInfo = null;
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            UnionMember member = CrossUnionMgr.getUnionMemberByUserId(player.getUserId());
            if (member == null || StringUtils.isNullOrEmpty(member.getUnionUid())
                || (member.getPosition() != eUnionPosition.Master.getValue() && member.getPosition() != eUnionPosition.DeputyMaster.getValue())) {
                return GameErrorCode.E_UNION_POSITION_NO_ENOUGH;
            }
            unionInfo = CrossUnionMgr.getUnionInfo(member.getUnionUid());
            if (unionInfo == null) {
                return GameErrorCode.E_UNION_NO_JOIN_UNION;
            }
            if (unionInfo.getDeleteCoolingOffTime()  <= 0) {
                return GameErrorCode.E_UNION_OUT_DELETE_COOLING_OFF_TIME;
            }
            unionInfo.setDeleteCoolingOffTime(0);
            sendUnionChangeBroadcast(eUnionSyncType.Normal.getValue(), unionInfo, null, null, 0);

            CrossAutoLogMgr.add(new LogUnionDelete(player.getUserId(), unionInfo.getUnionUid(), unionInfo.getMasterUserId(),
                    unionInfo.getExperience(), unionInfo.getWealth(), eUnionDeleteState.CancelDelete.getValue()));

            //增加商会日志
            CrossUnionNoticeMgr.addNotice(player, unionInfo.getUnionUid(), eUnionNoticeType.CancelDelete.getValue(), "");
        }
        return 0;
    }

    private static void removeFormUnion(CrossUserBaseInfo player, CrossUnionInfo unionInfo, CrossUnionMember removeMember, int removeType) {
        if (eUnionSyncType.BeKick.getValue() != removeType) {
            player.getUserBaseInfo().setUnionUid("");
            //Redis修改角色商会信息
            if(ChannelConfig.USER_INFO_USE_REDIS == 1) {
                try {
                    RedisManger.getRedisUtil().setString("user_base_info:" + removeMember.getUserId(), JSON.toJSONString(player.getUserBaseInfo()));
                } catch (Exception e) {
                    getLogger().error("update user info to redis fail,userId:{},error:", removeMember.getUserId(), e);
                }
            }
        }
        removeMember.setUnionUid("");
        long quitTime = System.currentTimeMillis() / 1000;
        removeMember.setQuitTime(quitTime);
        if (eUnionSyncType.BeKick.getValue() == removeType || eUnionSyncType.DeleteUnion.getValue() == removeType) {
            removeMember.setKickTime(quitTime);
            if (GameConfig.UNION_NEXT_JOIN_NEED_TIME >= 10 * DateHelper.MINUTE_SECONDS) {
                removeMember.setQuitTime(quitTime - GameConfig.UNION_NEXT_JOIN_NEED_TIME + 10 * DateHelper.MINUTE_SECONDS);
            }
            //为什么写这么复杂，历史代码quiteTime记录的不是准确的退出时间，而是把冷却时间计算在内；
            //10分钟内被踢，沒有冷却时间；
            if(eUnionSyncType.BeKick.getValue() == removeType && quitTime - removeMember.getJoinTime() < 10 * DateHelper.MINUTE_SECONDS){
                removeMember.setQuitTime(quitTime - GameConfig.UNION_NEXT_JOIN_NEED_TIME);
            }
        }
        long oldContribution = removeMember.getContribution();
        removeMember.setContribution(CrossUnionConfigMgr.getLoseContribution(removeMember.getContribution()));
        //清除议事厅数据
        removeMember.setChamberPatronsId(0);
        //removeMember.setChamberPatrons(null);
        //设置职位信息成普通成员
        removeMember.setPosition(eUnionPosition.Member.getValue());
        long nowContribution = removeMember.getContribution();
        removeMember.setLose(oldContribution - nowContribution);
        int son = 0;
        if (eUnionSyncType.QuitUnion.getValue() == removeType) {
            son = eLogMoneyType.UnionQuit.getValue();
        } else if (eUnionSyncType.BeKick.getValue() == removeType) {
            son = eLogMoneyType.UnionBeKick.getValue();
        } else if (eUnionSyncType.DeleteUnion.getValue() == removeType) {
            son = eLogMoneyType.UnionDelete.getValue();
        }
        //清理副业数据
        CrossUnionParergonMgr.quitUnion(unionInfo.getUnionUid(), removeMember.getUserId());

        CrossAutoLogMgr.add(new LogUnionContribution(removeMember.getUserId(), unionInfo.getUnionUid(), false, oldContribution - nowContribution,
                oldContribution, nowContribution, son));

        addMemberToDeleteMap(removeMember);

        notifyAllMemberChamberChange(unionInfo.getUnionUid(), removeMember.getUserId(), true, null);

        removeMemberFromMap(unionInfo.getUnionUid(), removeMember.getUserId());
        unionInfo.setMemberCount(getUnionMemberCount(unionInfo.getUnionUid()));
        calcUnionEarnSpeed(unionInfo);

        // 更新下商会活动分组
        UnionActivityGroupLockMgr.getThreadTaskManger().addTask(0, new GeneralTask() {
            @Override
            public void doRun() {
                UnionActivityGroupLockMgr.onUnionChange(unionInfo.getUnionUid());
                UnionActivityGroupLockMgr.updateMemberPosition(unionInfo.getUnionUid(), removeMember.getUserId());
            }
        });

    }

    /**
     * 商会建设
     */
    public static CrossUnionProto.UnionConstructionCrossRespMsg.Builder constructUnion(long playerId, int constructionType, String consume){
        CrossUnionProto.UnionConstructionCrossRespMsg.Builder respMsg = CrossUnionProto.UnionConstructionCrossRespMsg.newBuilder();
        if(!StringUtils.isNullOrEmpty(consume)){
            respMsg.setConsume(consume);
        }
        UnionConstructConfig unionConstructConfig = CrossUnionConfigMgr.getUnionConstructConfig(constructionType);
        if (null == unionConstructConfig) {
            respMsg.setRet(GameErrorCode.E_UNION_CONSTRUCT_TYPE_ERROR);
            return respMsg;
        }
        respMsg.setConstructionType(constructionType);
        CrossUserBaseInfo player = CrossUserMgr.getCrossUserBaseInfo(playerId);
        if(player == null){
            respMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
            return respMsg;
        }
        long serverId = player.getUserBaseInfo().getServerId();
        CrossUnionMember member = getUnionMember(player.getUserBaseInfo().getUnionUid(),playerId);
        if (member == null) {
            respMsg.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
            return respMsg;
        }
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            CrossUnionInfo unionInfo = getUnionInfo(member.getUnionUid());
            if (null == unionInfo) {
                respMsg.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
                return respMsg;
            }
            resetUnionDailyData(unionInfo);
            resetMemberDailyData(member);

            int constructTimes = member.getConstructTimes(constructionType);
            if (constructTimes >= unionConstructConfig.getMaxTimes()) {
                respMsg.setRet(GameErrorCode.E_UNION_CONSTRUCT_TIME_OVER);
                return respMsg;
            }
            long nowTime = System.currentTimeMillis() / 1000;
            long lastConstructTime = member.getLastConstructTime(constructionType);
            if (nowTime - lastConstructTime < unionConstructConfig.getCoolTime()) {
                respMsg.setRet(GameErrorCode.E_UNION_CONSTRUCT_COOL_TIME);
                return respMsg;
            }
            int crossServerCount = CrossUnionServerGroupMgr.getGroupServerCountByServerId(unionInfo.getServerId());
            if (!unionInfo.hasConstructUserId(playerId)
                    && unionInfo.getConstructUserCount() >= (CrossUnionConfigMgr.getMaxMemberCount(unionInfo.getExperience(), unionInfo.isCross(), crossServerCount) +
                    GameConfig.UNION_CONSTRUCTION_MAX_ADD_MEMBER_COUNT)
            ) {
                respMsg.setRet(GameErrorCode.E_UNION_CONSTRUCT_MEMBER_OVER);
                return respMsg;
            }

            //增加建设次数
            member.addConstructTimes(constructionType);
            unionInfo.addConstructUserId(playerId);
            unionInfo.setConstructActive(unionInfo.getConstructActive() + unionConstructConfig.getAddProgress());

            //奖励

            //addUnionExp(player, unionInfo.getUnionUid(), unionConstructConfig.getAddUnionExp(), eLogMoneyType.Union, eLogMoneyType.UnionConstruct.getValue());
            //addUnionWealth(player, unionInfo, unionConstructConfig.getAddUnionWealth(), eLogMoneyType.Union, eLogMoneyType.UnionConstruct.getValue() );
            //addContribution(unionConstructConfig.getAddContribution(), unionInfo, member, eLogMoneyType.UnionConstruct.getValue());

            //增加联盟日志
            CrossUnionNoticeMgr.addNotice(player, unionInfo.getUnionUid(), eUnionNoticeType.ConstructUnion.getValue(), String.valueOf(constructionType));

            MessageHelper.sendPacket(member.getServerId(), member.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_UNION_DETAIL, getUnionDetailMsg(unionInfo, eUnionSyncType.Normal.getValue())));
            //给在线成员推送联盟信息
            //sendUnionChangeBroadcast(eUnionSyncType.Normal.getValue(), unionInfo, player, null, 0);
        }
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 一键领取建设宝箱奖励(助理)
     */
    public static AssistantProto.AssistantCommonResult.Builder oneKeyReceiveUnionConstructActiveReward(long serverId, long userId){
        AssistantProto.AssistantCommonResult.Builder builder = AssistantProto.AssistantCommonResult.newBuilder();
        builder.setId(AssistantProto.AssistantActionType.UNION_RECEIVE_BOX.getNumber());
        CrossUserBaseInfo crossUserBaseInfo = CrossUserMgr.getCrossUserBaseInfo(userId);
        if(crossUserBaseInfo == null){
            builder.setRet(GameErrorCode.E_USER_NO_FOUND);
            return builder;
        }

        CrossUnionMember member = CrossUnionMgr.getUnionMember(crossUserBaseInfo.getUserBaseInfo().getUnionUid(), userId);
        if(member == null || StringUtils.isNullOrEmpty(member.getUnionUid())){
            builder.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
            return builder;
        }

        CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(member.getUnionUid());
        if(unionInfo == null){
            builder.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
            return builder;
        }
        Property reward = new Property();
        boolean flag = false;
        for(Integer constructActive : ConfigMgr.getUnionConstructActiveList()){
            int index = ConfigMgr.getUnionConstructActiveIndex(constructActive);
            if (-1 == index) {
                continue;
            }
            if(isCanRewardConstruct(unionInfo, member, constructActive) != 0){
                continue;
            }
            member.addConstructRewardIndex(constructActive);
            reward.addProperty(ConfigMgr.getUnionConstructActiveReward(index));
            flag = true;
        }
        if(!flag){
            builder.setRet(GameErrorCode.E_UNION_CONSTRUCT_ACTIVE_NO_ENOUGH);
            return builder;
        }
        if (reward.getGoods().size() > 0) {
            //player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.Union, eLogMoneyType.UnionConstructActive);
            builder.setReward(PropertyHelper.parsePropertyToString(reward));
        }
        //player.sendChannelPacket(Protocol.U_UNION_DETAIL, UnionMgr.getUnionDetailMsg(unionUid, eUnionSyncType.Normal.getValue()));
        builder.setRet(0);
        return builder;
    }

    /**
     * 商会建设（助理）
     */
    public static AssistantProto.AssistantUnionCrossBuildResultTemp.Builder assistantConstructUnion(long playerId, int constructionType, String consume){
        AssistantProto.AssistantUnionCrossBuildResultTemp.Builder respMsg = AssistantProto.AssistantUnionCrossBuildResultTemp.newBuilder();
        if(!StringUtils.isNullOrEmpty(consume)){
            respMsg.setConsume(consume);
        }

        UnionConstructConfig unionConstructConfig = CrossUnionConfigMgr.getUnionConstructConfig(constructionType);
        if (null == unionConstructConfig) {
            respMsg.setRet(GameErrorCode.E_UNION_CONSTRUCT_TYPE_ERROR);
            return respMsg;
        }
        respMsg.setConstructionType(constructionType);
        CrossUserBaseInfo player = CrossUserMgr.getCrossUserBaseInfo(playerId);
        if(player == null){
            respMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
            return respMsg;
        }
        long serverId = player.getUserBaseInfo().getServerId();
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            CrossUnionMember member = getUnionMemberByUserId(playerId);
            if (member == null || StringUtils.isNullOrEmpty(member.getUnionUid())) {
                respMsg.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
                return respMsg;
            }
            CrossUnionInfo unionInfo = getUnionInfo(member.getUnionUid());
            if (null == unionInfo) {
                respMsg.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
                return respMsg;
            }
            resetUnionDailyData(unionInfo);
            resetMemberDailyData(member);

            int constructTimes = member.getConstructTimes(constructionType);
            if (constructTimes >= unionConstructConfig.getMaxTimes()) {
                respMsg.setRet(GameErrorCode.E_UNION_CONSTRUCT_TIME_OVER);
                return respMsg;
            }
            long nowTime = System.currentTimeMillis() / 1000;
            long lastConstructTime = member.getLastConstructTime(constructionType);
            if (nowTime - lastConstructTime < unionConstructConfig.getCoolTime()) {
                respMsg.setRet(GameErrorCode.E_UNION_CONSTRUCT_COOL_TIME);
                return respMsg;
            }
            int crossServerCount = CrossUnionServerGroupMgr.getGroupServerCountByServerId(unionInfo.getServerId());
            if (!unionInfo.hasConstructUserId(playerId)
                    && unionInfo.getConstructUserCount() >= (CrossUnionConfigMgr.getMaxMemberCount(unionInfo.getExperience(), unionInfo.isCross(), crossServerCount) +
                    GameConfig.UNION_CONSTRUCTION_MAX_ADD_MEMBER_COUNT)) {
                respMsg.setRet(GameErrorCode.E_UNION_CONSTRUCT_MEMBER_OVER);
                return respMsg;
            }

            //增加建设次数
            member.addConstructTimes(constructionType);
            unionInfo.addConstructUserId(playerId);
            unionInfo.setConstructActive(unionInfo.getConstructActive() + unionConstructConfig.getAddProgress());

            //增加联盟日志
            CrossUnionNoticeMgr.addNotice(player, unionInfo.getUnionUid(), eUnionNoticeType.ConstructUnion.getValue(), String.valueOf(constructionType));

            MessageHelper.sendPacket(member.getServerId(), member.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_UNION_DETAIL, getUnionDetailMsg(unionInfo, eUnionSyncType.Normal.getValue())));

        }
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 位置变更
     */
    public static UnionProto.UnionPositionSetRespMsg.Builder setPosition(long playerId, long operateUserId, int position, boolean isBackend) {

        UnionProto.UnionPositionSetRespMsg.Builder respMsg = UnionProto.UnionPositionSetRespMsg.newBuilder();

        CrossUserBaseInfo player = CrossUserMgr.getCrossUserBaseInfo(playerId);
        if(player == null){
            respMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
            return respMsg;
        }

        String unionUid = player.getUserBaseInfo().getUnionUid();
        if(StringUtils.isNullOrEmpty(unionUid)){
            respMsg.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
            return respMsg;
        }
        CrossUnionMember member = CrossUnionMgr.getUnionMember(unionUid, playerId);
        if(null == member){
            respMsg.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
            return respMsg;
        }

        CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(member.getUnionUid());
        if(unionInfo == null){
            respMsg.setRet(GameErrorCode.E_UNION_NO_JOIN_UNION);
            return respMsg;
        }

        synchronized (CrossUnionLockerMgr.getGourpLocker(unionInfo.getServerId())) {

            // 判断权限 族长 副族长才有权限
            if (!hasApplyPassRole(member)) {
                respMsg.setRet(GameErrorCode.E_UNION_POSITION_NO_ENOUGH);
                return respMsg;
            }

            CrossUnionMember operateMember = getUnionMember(unionUid, operateUserId);
            if (null == operateMember) {
                respMsg.setRet(GameErrorCode.E_UNION_MEMBER_NO_FOUND);
                return respMsg;
            }
            if (!isBackend && !CrossUnionConfigMgr.isContributionEnough(operateMember.getTotalContribution(), position)) {
                respMsg.setRet(GameErrorCode.E_UNION_CONTRIBUTION_NOT_ENOUGH);
                return respMsg;
            }

            // 转让族长
            int oldOperatePosition = operateMember.getPosition();
            if (position == eUnionPosition.Master.getValue()) {
                if (member.getPosition() == eUnionPosition.Master.getValue()) {
                    operateMember.setPosition(position);
                    member.setPosition(eUnionPosition.Member.getValue());

                    unionInfo.setDecoration(operateMember.getUserBaseInfo().getDecoration());
                    unionInfo.setVipExp(operateMember.getUserBaseInfo().getVipExp());
                    unionInfo.setMasterNickName(operateMember.getUserBaseInfo().getNickName());
                    unionInfo.setMasterUserId(operateMember.getUserId());

                    //增加联盟日志
                    CrossUnionNoticeMgr.addNotice(player, unionUid, eUnionNoticeType.ChangeMaster.getValue(), operateMember.getUserBaseInfo().getNickName());

                    CrossAutoLogMgr.add(new LogUnionChangeMaster(unionUid, false, player.getUserId(), operateUserId));
                } else {
                    respMsg.setRet(GameErrorCode.E_UNION_POSITION_NO_ENOUGH);
                    return respMsg;
                }
            } else {
                // 判断当前职位个数
                if (CrossUnionConfigMgr.isPositionCountMax(unionInfo, getUnionMemberMap(unionUid), position)) {
                    respMsg.setRet(GameErrorCode.E_UNION_POSITION_COUNT_FULL);
                    return respMsg;
                }
                // 族长副族长不能被设置职位
                if (operateMember.getPosition() == eUnionPosition.Master.getValue()) {
                    respMsg.setRet(GameErrorCode.E_UNION_POSITION_NO_ENOUGH);
                    return respMsg;
                }
                // 副族长只能被族长设置职位
                if (operateMember.getPosition() == eUnionPosition.DeputyMaster.getValue()) {
                    if (member.getPosition() != eUnionPosition.Master.getValue()) {
                        respMsg.setRet(GameErrorCode.E_UNION_POSITION_NO_ENOUGH);
                        return respMsg;
                    }
                }
                operateMember.setPosition(position);

                //增加联盟日志
                CrossUnionNoticeMgr.addNotice(player, unionUid, eUnionNoticeType.ChangePosition.getValue(), operateMember.getUserBaseInfo().getNickName(), String.valueOf(position));
            }

            sendUnionChangeBroadcast(eUnionSyncType.SetPosition.getValue(), unionInfo, player, null, operateUserId);

            //如果职位由普通变成管理，需要下发申请列表
            if ((position == eUnionPosition.Master.getValue() || position == eUnionPosition.DeputyMaster.getValue()) &&
                    (oldOperatePosition != eUnionPosition.Master.getValue() && oldOperatePosition != eUnionPosition.DeputyMaster.getValue())) {
                CrossUserBaseInfo operatePlayer = CrossUserMgr.getCrossUserBaseInfo(operateUserId);
                if (null != operatePlayer) {
                    CrossUnionJoinApplyMgr.sendJoinApplyList(operatePlayer, unionUid);
                }
            }

            UnionProto.UnionMemberTempMsg.Builder memberMsg = CrossUnionPb.parseUnionMemberTempMsg(member);
            if (null != memberMsg) {
                respMsg.setMember(memberMsg);
            }

            respMsg.setRet(0);

            // 更新下商会活动分组
            UnionActivityGroupLockMgr.getThreadTaskManger().addTask(0, new GeneralTask() {
                @Override
                public void doRun() {
                    UnionActivityGroupLockMgr.onUnionChange(unionInfo.getUnionUid());
                    if (position == eUnionPosition.Master.getValue()) {
                        UnionActivityGroupLockMgr.updateMemberPosition(unionInfo.getUnionUid(), playerId, operateUserId);
                    } else {
                        UnionActivityGroupLockMgr.updateMemberPosition(unionInfo.getUnionUid(), operateUserId);
                    }
                }
            });

        }
        return respMsg;
    }

    public static int changeApplyTitle(long serverId, long playerId, int title) {

        CrossUnionReqContext context = CrossUnionReqContext.initContext(serverId, playerId).loadUnionMember().loadUnionInfo();
        if(context.getRet() != 0){
            return context.getRet();
        }

        if (context.getMember().getPosition() != eUnionPosition.Master.getValue() && context.getMember().getPosition() != eUnionPosition.DeputyMaster.getValue()) {
            return GameErrorCode.E_UNION_POSITION_NO_ENOUGH;
        }
        int minTitle = CrossUnionConfigMgr.getMinApplyTitle();
        int maxTitle = CrossUnionConfigMgr.getMaxApplyTitle();
        if (title != 0 && (title < minTitle || title > maxTitle)) {
            return GameErrorCode.E_UNION_APPLY_TITLE_NO_IN_RANGE;
        }

        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            context.getUnionInfo().setApplyTitleLimit(title);
        }

        sendUnionChangeBroadcast(eUnionSyncType.Normal.getValue(), context.getUnionInfo(), context.getUserBaseInfo(), null, 0);
        return 0;
    }

    /**
     * 议事厅派遣
     */
    public static int chamberDispatch(long serverId, long playerId, CrossUnionChamberPatrons chamberPatrons, boolean needBack, int patronsId) {
        CrossUnionReqContext context = CrossUnionReqContext.initContext(serverId, playerId).loadUnionMember().loadUnionInfo();
        if(context.getRet() != 0){
            return context.getRet();
        }

        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)){
            UnionInfo unionInfo = context.getUnionInfo();

            if(patronsId > 0) {
                PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(patronsId);
                int count = CrossUnionConfigMgr.getUnionChamberOccupationPatronsCount(patronsInfo.getOccupation(), unionInfo.getUnionUid(), playerId);
                if (count >= GameConfig.UNION_CHAMBER_PATRONS_LIMIT) {
                    return GameErrorCode.E_UNION_CHAMBER_PATRONS_OVER_COUNT;
                }
            }

            CrossUnionMember member = context.getMember();
            int oldPatronsId = member.getChamberPatronsId();
            member.setChamberPatronsId(patronsId);

            if(member.getChamberPatrons() == null){
                if(chamberPatrons != null) {
                    chamberPatrons.setInsertOption();
                    addCrossUnionChamberPatrons(chamberPatrons);
                    member.setChamberPatrons(chamberPatrons);
                }
            }else {
                if(chamberPatrons != null) {
                    member.setChamberPatronsId(chamberPatrons.getPatronsId());
                    setChamber(member, chamberPatrons);
                }else {
                    clearCrossUnionChamberPatrons(member.getChamberPatrons());
                }
                member.setUpdateOption();
            }

            notifyAllMemberChamberChange(context.getUnionInfo().getUnionUid(), playerId, patronsId == 0, chamberPatrons);
            if(needBack) {
                CrossUnionProto.UnionChamberDispatchCrossRespMsg.Builder crossRespMsg = CrossUnionProto.UnionChamberDispatchCrossRespMsg.newBuilder();
                crossRespMsg.setPatronsId(patronsId);
                crossRespMsg.setOldPatronsId(oldPatronsId);
                crossRespMsg.setUnionUid(member.getUnionUid());
                crossRespMsg.setTotalEarnSpeed(String.valueOf(getChamberPatronsTotalEarnSpeed(context.getUnionInfo())));
                crossRespMsg.setRet(0);
                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_UNION_CHAMBER_DISPATCH_FROM_CROSS, crossRespMsg));
                MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_CHAMBER_DISPATCH, UnionProto.UnionChamberDispatchRespMsg.newBuilder().setRet(0)));
            }
            sendUnionChangeBroadcast(eUnionSyncType.ChamberPatrons.getValue(), context.getUnionInfo(), context.getUserBaseInfo(), null, 0);
        }
        return 0;
    }

    private static void clearCrossUnionChamberPatrons(CrossUnionChamberPatrons chamberPatrons) {
        chamberPatrons.setPromotionId(0);
        chamberPatrons.setSkinId(0);
        chamberPatrons.setBreakLv(0);
        chamberPatrons.setStageLv(0);
        chamberPatrons.setLevel(0);
        chamberPatrons.setPatronsId(0);
        chamberPatrons.setAbility(BigInteger.ZERO);
        chamberPatrons.setSkillList(new ArrayList<>());
    }

    private static void setChamber(CrossUnionMember member, CrossUnionChamberPatrons chamberPatrons) {
        member.getChamberPatrons().setPromotionId(chamberPatrons.getPromotionId());
        member.getChamberPatrons().setSkinId(chamberPatrons.getSkinId());
        member.getChamberPatrons().setBreakLv(chamberPatrons.getBreakLv());
        member.getChamberPatrons().setStageLv(chamberPatrons.getStageLv());
        member.getChamberPatrons().setLevel(chamberPatrons.getLevel());
        member.getChamberPatrons().setPatronsId(chamberPatrons.getPatronsId());
        member.getChamberPatrons().setAbility(chamberPatrons.getAbility());
        member.getChamberPatrons().setSkillList(chamberPatrons.getSkillList());
    }

    public static int changeUnionFlag(long serverId, long playerId, int unionFlag) {

        CrossUnionReqContext context = CrossUnionReqContext.initContext(serverId, playerId).loadUnionMember().loadUnionInfo();
        if(context.getRet() != 0){
            return context.getRet();
        }

        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)){
            CrossUnionInfo unionInfo = context.getUnionInfo();
            if (unionInfo.getMasterUserId() != playerId) {//权限不足
                return GameErrorCode.E_UNION_POSITION_NO_ENOUGH;
            }
            if(!CrossUnionMgr.hasUnionFlag(unionInfo.getUnionUid(), unionFlag)){
                return GameErrorCode.E_UNION_FLAG_NO_FOUND;
            }

            long nowTime = System.currentTimeMillis() / 1000;
            if (nowTime - unionInfo.getFlagModifyTime() < 3600) {
                return GameErrorCode.E_UNION_FLAG_CHANGE_TIME_ONE_HOUR;
            }

            int preUnionFlag = unionInfo.getUnionFlag();
            if (ConfigMgr.hasUnionFlag(preUnionFlag)) {
                //如果是默认的会旗，则记录
                unionInfo.setPreUnionFlag(preUnionFlag);
            }
            unionInfo.setUnionFlag(unionFlag);
            unionInfo.setFlagModifyTime(nowTime);
            //清除组合旗帜
            unionInfo.setUnionFlagStr("");
            //增加联盟日志
            CrossUnionNoticeMgr.addNotice(context.getUserBaseInfo(), unionInfo.getUnionUid(), eUnionNoticeType.UnionModify.getValue(), "");

            //
            UnionProto.UnionChangeRandomJoinRespMsg.Builder respMsg = UnionProto.UnionChangeRandomJoinRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setUnion(CrossUnionPb.parseUnionTempMsg(unionInfo));
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_CHANGE_FLAG, respMsg));

            CrossUnionMgr.sendUnionChangeBroadcast(eUnionSyncType.Normal.getValue(), context.getUnionInfo(), context.getUserBaseInfo(), null, 0);
        }

        return 0;
    }

    public static int changeUnionFlag(long serverId, long playerId, List<Integer> flagList) {

        CrossUnionReqContext context = CrossUnionReqContext.initContext(serverId, playerId).loadUnionMember().loadUnionInfo();
        if(context.getRet() != 0){
            return context.getRet();
        }

        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)){
            CrossUnionInfo unionInfo = context.getUnionInfo();
            if (unionInfo.getMasterUserId() != playerId) {//权限不足
                return GameErrorCode.E_UNION_POSITION_NO_ENOUGH;
            }

            for (int i = 0; i < flagList.size(); i++) {
                int unionFlag = flagList.get(i);
                if(!CrossUnionMgr.hasUnionFlag(unionInfo.getUnionUid(), unionFlag)){
                    return GameErrorCode.E_UNION_FLAG_NO_UNLOCK;
                }
                GoodsInfo goodsInfo = GoodsMgr.getGoodsInfo(unionFlag);
                if(goodsInfo == null){
                    return GameErrorCode.E_UNION_FLAG_NO_FOUND;
                }
                //类型  头/面/饰  顺序
                if((i + 1) != goodsInfo.getParamList().get(2).intValue()){
                    return GameErrorCode.E_UNION_FLAG_TYPE_ERROR;
                }
            }

            long nowTime = System.currentTimeMillis() / 1000;
            if (nowTime - unionInfo.getFlagModifyTime() < 3600) {
                return GameErrorCode.E_UNION_FLAG_CHANGE_TIME_ONE_HOUR;
            }

            unionInfo.setUnionFlagStr(StringUtils.listToString(flagList, StringUtils.SEPARATOR));
            unionInfo.setFlagModifyTime(nowTime);

            //增加联盟日志
            CrossUnionNoticeMgr.addNotice(context.getUserBaseInfo(), unionInfo.getUnionUid(), eUnionNoticeType.UnionModify.getValue(), "");

            //
            CrossUnionHonorsProto.CrossUnionModifyFlagRespMsg.Builder respMsg = CrossUnionHonorsProto.CrossUnionModifyFlagRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setUnion(CrossUnionPb.parseUnionTempMsg(unionInfo));
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_CHANGE_FLAG_NEW, respMsg));

            CrossUnionMgr.sendUnionChangeBroadcast(eUnionSyncType.Normal.getValue(), context.getUnionInfo(), context.getUserBaseInfo(), null, 0);
        }

        return 0;
    }

    /**
     * 副业经营
     */
    public static UnionParergonOperateResult parergonOperate(long serverId, long playerId, int parergonId, int type, int operateTimes) {

        UnionParergonOperateResult result = new UnionParergonOperateResult();

        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            CrossUnionReqContext context = CrossUnionReqContext.initContext(serverId, playerId).loadUnionMember().loadUnionInfo();
            if (context.getRet() != 0) {
                result.setRet(context.getRet());
                return result;
            }

            UnionParergonPlayer parergonPlayer = CrossUnionParergonMgr.getParergonPlayer(context.getPlayerId());

//        synchronized (parergonPlayer) {

            CrossUnionParergonMgr.calOperateTimes(parergonPlayer);
            if (parergonPlayer.getOperateTimes() <= 0) {
                result.setRet(GameErrorCode.E_PARERGON_OPERATE_NOT_TIMES);
                result.setOperateTimes(parergonPlayer.getOperateTimes());
                result.setLastRestoreTime(parergonPlayer.getLastRestoreTime());
                return result;
            }

            if(operateTimes == 0){
                operateTimes = parergonPlayer.getOperateTimes();
            }

            if (type == 0) {
                //经营
                result = CrossUnionParergonMgr.operate(context.getUnionInfo().getUnionUid(), parergonId, context.getMember());
            } else {
                //一键经营
                result = CrossUnionParergonMgr.oneKeyOperate(parergonPlayer, context.getUnionInfo().getUnionUid(), parergonId, context.getMember(), operateTimes);
            }
            if (result.getRet() != 0) {
                return result;
            }
            //刷新次数
            parergonPlayer.setOperateTimes(parergonPlayer.getOperateTimes() - result.getOperateTimes());
            result.setFinishTimes(result.getOperateTimes());

            //增加经营次数
            parergonPlayer.setTodayTimes(parergonPlayer.getTodayTimes() + result.getOperateTimes());
            parergonPlayer.setTotalTimes(parergonPlayer.getTotalTimes() + result.getOperateTimes());
            parergonPlayer.setHistoryTimes(parergonPlayer.getHistoryTimes() + result.getOperateTimes());

            result.setHistoryTimes(parergonPlayer.getHistoryTimes());
            //
            result.setOperateTimes(parergonPlayer.getOperateTimes());
            result.setLastRestoreTime(parergonPlayer.getLastRestoreTime());

//          }
          MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_UNION_PARERGON_OPERATE_FROM_CROSS, CrossUnionParergonMgr.builderOperateRespMsg(result)));
        }
        return result;
    }

    /**
     * 玩家登录
     */
    public static void userLogin(long serverId, long playerId, String unionUid) {

        CrossUnionMember member = getUnionMemberByUserId(playerId);
        CrossUserBaseInfo userBaseInfo = CrossUserMgr.getCrossUserBaseInfo(playerId);

        // 先设置下登录时间
        setLastLoginTime(member, userBaseInfo);

        // 检查下活动
        UnionActivityGroupLockMgr.checkAddUnionData(playerId);

        //发循环到的系统
        List<Integer> systemIds = CrossSystemLoopMgr.getNowWeekSystemIds(serverId);
        MessageHelper.sendPacket(serverId, playerId,
                YanQuMessageUtils.buildMessage(ClientProtocol.U_SYSTEM_LOOP_SYNC, ServerProto.SystemLoopSyncMsg.newBuilder().addAllSystemId(systemIds)));

        if(member != null){
            if(null != userBaseInfo){
                if(!Objects.equals(member.getUnionUid(), userBaseInfo.getUserBaseInfo().getUnionUid())) {
                    userBaseInfo.getUserBaseInfo().setUnionUid(member.getUnionUid());
                    //Redis修改角色商会信息
                    if(ChannelConfig.USER_INFO_USE_REDIS == 1) {
                        try {
                            RedisManger.getRedisUtil().setString("user_base_info:" + playerId, JSON.toJSONString(userBaseInfo.getUserBaseInfo()));
                        } catch (Exception e) {
                            logger.error("update user info to redis fail,userId:{},error:", playerId, e);
                        }
                    }
                }
            }
            if(Objects.equals(unionUid, member.getUnionUid())){
                //归属商会信息一致
                CrossUnionInfo unionInfo = getUnionInfo(member.getUnionUid());
                if(unionInfo == null){

                    MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_DETAIL, getUnionDetailMsg(unionUid, eUnionSyncType.Normal.getValue())));

                }else {

                    MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_DETAIL, getUnionDetailMsg(unionInfo, eUnionSyncType.Normal.getValue())));
                    if(hasApplyPassRole(member)){
                        //下发申请列表（全量）
                        CrossUserBaseInfo baseInfo = CrossUserMgr.getCrossUserBaseInfo(member.getUserId());
                        CrossUnionJoinApplyMgr.sendJoinApplyList(baseInfo, member.getUnionUid());
                    }

                    //副业
                    CrossUnionParergonMgr.sycnUserAllParergonData(userBaseInfo);
                }
            }else if(StringUtils.isNullOrEmpty(member.getUnionUid())){
                //不归属任何商会
                CrossUnionInfo unionInfo = getUnionInfo(unionUid);
                if(unionInfo == null){
                    MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_DETAIL, getUnionDetailMsg("", eUnionSyncType.DeleteUnion.getValue())));
                }else {
                    //数据容易与区服数据不一致，不提示（玩家自己看邮件吧）
                    //MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_DETAIL, getUnionDetailMsg("", eUnionSyncType.BeKick.getValue())));
                }

                return;
            }else {
                //加入商会
                CrossUnionInfo unionInfo = getUnionInfo(member.getUnionUid());
                if(unionInfo != null){
                    MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_DETAIL, getUnionDetailMsg(unionInfo, eUnionSyncType.JoinUnion.getValue())));

                    if(hasApplyPassRole(member)){
                        //下发申请列表（全量）
                        CrossUserBaseInfo baseInfo = CrossUserMgr.getCrossUserBaseInfo(member.getUserId());
                        CrossUnionJoinApplyMgr.sendJoinApplyList(baseInfo, member.getUnionUid());
                    }

                    //副业
                    CrossUnionParergonMgr.sycnUserAllParergonData(userBaseInfo);
                }
            }
            syncUnionMember(member);
            //syncCrossGroup(member);
            CrossUnionHuaBenMgr.userLogin(serverId, playerId);
        } else {
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.U_UNION_DETAIL, getUnionDetailMsg("", eUnionSyncType.Normal.getValue())));
        }
    }

    private static void setLastLoginTime(CrossUnionMember member, CrossUserBaseInfo userBaseInfo) {
        try {
            long now = System.currentTimeMillis() / 1000;
            if (member != null) {
                member.getUserBaseInfo().setLastLoginTime(now);
                member.setUpdateOption();
            }
            if (userBaseInfo != null) {
                userBaseInfo.getUserBaseInfo().setLastLoginTime(now);
                userBaseInfo.setUpdateOption();
            }
        } catch (Exception e) {
            getLogger().error("error : ", e);
        }
    }

//    private static void syncCrossGroup(CrossUnionMember member) {
//        if(!StringUtils.isNullOrEmpty(member.getUnionUid())){
//            CrossUnionInfo unionInfo = getUnionInfo(member.getUnionUid());
//            if(unionInfo != null){
//                CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroupByServerId(unionInfo.getServerId());
//                CrossUnionProto.UnionServerGroupSyncMsg.Builder syncMsg = CrossUnionProto.UnionServerGroupSyncMsg.newBuilder();
//                if(serverGroup == null){
//                    syncMsg.setCrossOpen(false);
//                }else {
//                    syncMsg.setCrossOpen(serverGroup.getState() == 1);
//                    syncMsg.setGroupId(serverGroup.getGroupId());
//                    syncMsg.addAllServerList(new ArrayList<>(serverGroup.getServerList()));
//                }
//                MessageHelper.sendChannelPacket(member.getServerId(), member.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_UNION_CROSS_GROUP_SYNC, syncMsg));
//            }
//        }
//    }


    /**
     * 判断会长自动转让
     */
    public static void judgeChangeUnionOwner(CrossUnionMember member, String unionUid) {
        if(member == null || StringUtils.isNullOrEmpty(member.getUnionUid())){
            return;
        }
        CrossUnionInfo unionInfo = getUnionInfo(unionUid);
        if (null == unionInfo) {
            return;
        }
        synchronized (unionInfo) {
            CrossUnionMember masterMember = getMasterUnionMember(unionUid);
            if (null == masterMember) {
                return;
            }

            long offlineTime = System.currentTimeMillis() / 1000 - masterMember.getUserBaseInfo().getLastLoginTime();
            if (offlineTime >= GameConfig.UNION_MASTER_MAX_OFFLINE_TIME * DateHelper.DAY_SECONDS) {
                CrossUnionMember unionMember = findMasterUnionMember(unionUid, masterMember.getUserId());
                if (unionMember != null) {
                    int oldPosition = unionMember.getPosition();
                    unionMember.setPosition(eUnionPosition.Master.getValue());
                    masterMember.setPosition(eUnionPosition.Member.getValue());

                    unionInfo.setMasterUserId(unionMember.getUserId());
                    unionInfo.setMasterNickName(unionMember.getUserBaseInfo().getNickName());
                    unionInfo.setVipExp(unionMember.getUserBaseInfo().getVipExp());
                    unionInfo.setDecoration(unionMember.getUserBaseInfo().getDecoration());

                    //player.sendChannelPacket(Protocol.U_UNION_DETAIL, getUnionDetailMsg(unionUid, eUnionSyncType.Normal.getValue()));

                    CrossUnionNoticeMgr.addNotice(null, unionUid, eUnionNoticeType.AutoChangeMaster.getValue(), unionInfo.getMasterNickName());
                    //给成员同步商会信息
                    //notifyAllMemberUnionInfo(unionUid, player.getUserId());

                    //如果职位由普通变成管理，需要下发申请列表
                    if (oldPosition != eUnionPosition.Master.getValue() && oldPosition != eUnionPosition.DeputyMaster.getValue()) {
                        CrossUserBaseInfo userBaseInfo = CrossUserMgr.getCrossUserBaseInfo(unionMember.getUserId());
                        if (null != userBaseInfo) {
                            CrossUnionJoinApplyMgr.sendJoinApplyList(userBaseInfo, unionUid);
                        }
                    }
                    //商会冲榜
                    //notifyUnionActivityMasterChange(masterMember.getUserId(), unionUid);
                    //notifyUnionActivityMasterChange(unionMember.getUserId(), unionUid);
                    //变更商会信息
                    //RankMgr.changeUnionRank(unionInfo);
                    //UnionActivityMgr.changeUnionInfo(unionInfo);
                    CrossAutoLogMgr.add(new LogUnionChangeMaster(unionUid, true, masterMember.getUserId(), unionMember.getUserId()));
                    //商会战活动
                    //UnionPhaseWarMgr.memberPositionChange(unionInfo, masterMember.getUserId(), eUnionPosition.Member.getValue());
                    //UnionPhaseWarMgr.memberPositionChange(unionInfo, unionMember.getUserId(), eUnionPosition.Master.getValue());
                    //走镖
                    //BeautyEscortMgr.memberPositionChange(unionInfo, masterMember.getUserId(), eUnionPosition.Member.getValue());
                    //BeautyEscortMgr.memberPositionChange(unionInfo, unionMember.getUserId(), eUnionPosition.Master.getValue());

                    CrossUserBaseInfo masterUserInfo = CrossUserMgr.getCrossUserBaseInfo(masterMember.getUserId());

                    sendUnionChangeBroadcast(eUnionSyncType.SetPosition.getValue(), unionInfo, masterUserInfo, null, unionMember.getUserId());

                    // 更新下商会活动分组
                    UnionActivityGroupLockMgr.getThreadTaskManger().addTask(0, new GeneralTask() {
                        @Override
                        public void doRun() {
                            UnionActivityGroupLockMgr.onUnionChange(unionUid);
                        }
                    });

                }
            }
        }
    }

    private static CrossUnionMember getMasterUnionMember(String unionUid) {
        UnionInfo unionInfo = getUnionInfo(unionUid);
        if (null == unionInfo) {
            return null;
        }
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionUid);
        if (null != memberMap) {
            CrossUnionMember masterMember = memberMap.get(unionInfo.getMasterUserId());
            if (null == masterMember) {
                return null;
            }
            if (masterMember.getPosition() != eUnionPosition.Master.getValue()) {
                for (UnionMember unionMember : memberMap.values()) {
                    if (unionMember.getPosition() == eUnionPosition.Master.getValue()) {
                        unionMember.setPosition(eUnionPosition.Member.getValue());
                    }
                }
                masterMember.setPosition(eUnionPosition.Master.getValue());
            }
            return masterMember;
        }
        return null;
    }

    private static CrossUnionMember findMasterUnionMember(String unionUid, long userId) {
        CrossUnionMember unionMember;
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionUid);
        if (null == memberMap) {
            return null;
        }
        List<CrossUnionMember> deputyMasterList = new ArrayList<>();
        List<CrossUnionMember> eliteList = new ArrayList<>();
        List<CrossUnionMember> memberList = new ArrayList<>();
        for(CrossUnionMember member : memberMap.values()){
            if(member.getPosition() == eUnionPosition.DeputyMaster.getValue()){
                deputyMasterList.add(member);
            }else if(member.getPosition() == eUnionPosition.Elite.getValue()){
                eliteList.add(member);
            }else if(member.getPosition() == eUnionPosition.Member.getValue()){
                memberList.add(member);
            }
        }
        //先副会长
        unionMember = findNextMaster(deputyMasterList, userId);
        if(null != unionMember){
            return unionMember;
        }
        //再精英
        unionMember = findNextMaster(eliteList, userId);
        if(null != unionMember){
            return unionMember;
        }
        //最后成员
        unionMember = findNextMaster(memberList, userId);
        return unionMember;
    }

    /**
     * 查找符合条件的会长人选
     * @param memberList
     * @param oldMasterUserId
     * @return
     */
    private static CrossUnionMember findNextMaster(List<CrossUnionMember> memberList, long oldMasterUserId){
        CrossUnionMember unionMember = null;
        for (CrossUnionMember member : memberList) {
            if (member.getUserId() != oldMasterUserId) {
                long offlineTime = System.currentTimeMillis() / 1000 - member.getUserBaseInfo().getLastLoginTime();
                if (offlineTime < GameConfig.UNION_MASTER_MAX_OFFLINE_TIME * DateHelper.DAY_SECONDS) {
                    if (unionMember == null) {
                        unionMember = member;
                    } else if (member.getTotalContribution() > unionMember.getTotalContribution()) {
                        unionMember = member;
                    }
                }
            }
        }
        return unionMember;
    }

    //write
    public static void resetUnionDailyData(CrossUnionInfo unionInfo) {
        if (null == unionInfo) {
            return;
        }
        synchronized (unionInfo) {
            if (unionInfo.getModifyTime() < LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000) {
                unionInfo.setConstructUserIdList(new ArrayList<>());
                unionInfo.setConstructActive(0);
                unionInfo.setDayJoinNum(0);
                unionInfo.setDayKickNum(0);
                unionInfo.setModifyTime(System.currentTimeMillis() / 1000);
            }
        }
    }

    public static void resetMemberDailyData(UnionMember unionMember) {
        if (null == unionMember) {
            return;
        }
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000;
        synchronized (unionMember) {
            if (unionMember.getModifyTime() < zeroTime) {
                unionMember.setModifyTime(System.currentTimeMillis() / 1000);
                unionMember.setDonateTimes(0);
                unionMember.setConstructRewardIndexList(new ArrayList<>());
                unionMember.setUnionConstructMap(new ConcurrentHashMap<>());
                unionMember.setCacheTodayContribution(unionMember.getTodayContribution());
                unionMember.setTodayContribution(0);
                unionMember.setDayKickNum(0);
                unionMember.setDayCoolingOffNotice(false);
            }
        }
    }

    public static void addMemberToDeleteMap(CrossUnionMember unionMember) {
        deleteUnionMemberMap.put(unionMember.getUserId(), unionMember);
        allUnionMemberMap.put(unionMember.getUserId(), unionMember);
    }

    public static void addMemberToMap(CrossUnionMember unionMember) {
        if (null == unionMember) {
            return;
        }
        allUnionMemberMap.put(unionMember.getUserId(), unionMember);
        if (!unionMemberMap.containsKey(unionMember.getUnionUid())) {
            unionMemberMap.put(unionMember.getUnionUid(), new ConcurrentHashMap<>());
        }
        unionMemberMap.get(unionMember.getUnionUid()).put(unionMember.getUserId(), unionMember);

        updateUnionTotalMaxAbility(unionMember.getUnionUid());
    }

    private static void removeMemberFromDeleteMap(long userId) {
        deleteUnionMemberMap.remove(userId);
    }

    private static void removeMemberFromMap(String unionUid, long userId) {
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionUid);
        if (null != memberMap) {
            memberMap.remove(userId);
        }

        updateUnionTotalMaxAbility(unionUid);
    }

    public static void addCrossUnionChamberPatrons(CrossUnionChamberPatrons chamberPatrons){
        chamberPatronsMap.put(chamberPatrons.getUserId(), chamberPatrons);
    }

    public static void calcUnionEarnSpeed(UnionInfo unionInfo) {
        if (null == unionInfo) {
            return;
        }
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionInfo.getUnionUid());
        BigInteger totalEarnSpeed = BigInteger.ZERO;
        if (null != memberMap) {
            for (UnionMember unionMember : memberMap.values()) {
                totalEarnSpeed = totalEarnSpeed.add(unionMember.getUserBaseInfo().getEarnSpeed());
            }
        }
        unionInfo.setTotalEarnSpeed(totalEarnSpeed);
    }

    public static void readUnionFlag(String unionUid, List<Integer> flagList) {
        Map<Integer, CrossUnionFlag> flagMap = unionFlagMap.get(unionUid);
        if (flagMap == null) {
            return;
        }
        for (CrossUnionFlag flag : new ArrayList<>(flagMap.values())) {
            if(flagList.contains(flag.getFlagId())) {
                flag.setRead(true);
            }
        }
    }

    //仅商贸调用
    public static void addUnionExp(String unionUid, long exp, eLogMoneyType master, int son) {
        CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
        if (null == unionInfo) {
            return;
        }
        synchronized (unionInfo) {
            long originalExp = unionInfo.getExperience();
            UnionUpgradeInfo unionUpgradeInfo = CrossUnionConfigMgr.getUnionUpgradeInfo(unionInfo.getExperience());
            unionInfo.setExperience(unionInfo.getExperience() + exp);

            //联盟升级日志
            UnionUpgradeInfo newUnionUpgradeInfo = CrossUnionConfigMgr.getUnionUpgradeInfo(unionInfo.getExperience());
            if (null != unionUpgradeInfo && null != newUnionUpgradeInfo) {
                if (newUnionUpgradeInfo.getLevel() > unionUpgradeInfo.getLevel()) {
                    unionLevelUp(null, unionInfo,newUnionUpgradeInfo);
                }else {

                }
            }
            //商会经验活动
            unionInfo.setRankAddExp(unionInfo.getRankAddExp() + exp);
            CrossAutoLogMgr.add(new LogUnionExp(0L, unionUid, exp, originalExp, unionInfo.getExperience(), son));
        }
    }

    public static void addUnionExp(CrossUserBaseInfo player, String unionUid, long exp, eLogMoneyType master, int son) {
        CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
        if (null == unionInfo) {
            return;
        }
        synchronized (unionInfo) {
            long originalExp = unionInfo.getExperience();
            UnionUpgradeInfo unionUpgradeInfo = CrossUnionConfigMgr.getUnionUpgradeInfo(unionInfo.getExperience());
            unionInfo.setExperience(unionInfo.getExperience() + exp);


            //联盟升级日志
            UnionUpgradeInfo newUnionUpgradeInfo = CrossUnionConfigMgr.getUnionUpgradeInfo(unionInfo.getExperience());
            if (null != unionUpgradeInfo && null != newUnionUpgradeInfo) {
                if (newUnionUpgradeInfo.getLevel() > unionUpgradeInfo.getLevel()) {
                    unionLevelUp(player,unionInfo,newUnionUpgradeInfo);
                }else {

                }
            }
            long userId = 0;
            if (player != null) {
                userId = player.getUserId();
            }
            CrossAutoLogMgr.add(new LogUnionExp(userId, unionUid, exp, originalExp, unionInfo.getExperience(), son));
        }
    }

    /**
     * 联盟升级
     */
    public static void unionLevelUp(CrossUserBaseInfo player,CrossUnionInfo unionInfo, UnionUpgradeInfo newUnionUpgradeInfo){

        CrossUnionNoticeMgr.addNotice(player, unionInfo.getUnionUid(), eUnionNoticeType.UnionUpgrade.getValue(), String.valueOf(newUnionUpgradeInfo.getLevel()));

        sendUnionChangeBroadcast(eUnionSyncType.UpGrade.getValue(), unionInfo, player, null, 0);
    }

    public static void addUnionWealth(CrossUserBaseInfo player, CrossUnionInfo unionInfo, long wealth, eLogMoneyType master, int son) {
        synchronized (unionInfo) {
            long originalWealth = unionInfo.getWealth();
            unionInfo.setWealth(unionInfo.getWealth() + wealth);
            // 同步联盟信息

            CrossAutoLogMgr.add(new LogUnionWealth(player.getUserId(), unionInfo.getUnionUid(), true, wealth, originalWealth, unionInfo.getWealth(), son));
        }
    }

    public static long removeUnionWealth(CrossUserBaseInfo baseInfo, CrossUnionInfo unionInfo, long wealth, eLogMoneyType master, int son) {
        synchronized (unionInfo) {
            if (unionInfo.getWealth() - wealth < 0) {
                return 0;
            } else {
                long originalWealth = unionInfo.getWealth();
                unionInfo.setWealth(unionInfo.getWealth() - wealth);
                CrossAutoLogMgr.add(new LogUnionWealth(baseInfo.getUserId(), unionInfo.getUnionUid(), false, wealth, originalWealth, unionInfo.getWealth(), son));
                return wealth;
            }
        }
    }

    public static long addContribution(long value, CrossUnionInfo unionInfo, CrossUnionMember unionMember, int son) {
        if (value > 0) {
            if (null != unionMember) {
                long oldContribution = unionMember.getContribution();
                unionMember.setContribution(unionMember.getContribution() + value);
                unionMember.setTotalContribution(unionMember.getTotalContribution() + value);
                unionMember.setTodayContribution((int) (unionMember.getTodayContribution() + value));
                syncUnionMember(unionMember);

                CrossAutoLogMgr.add(new LogUnionContribution(unionMember.getUserId(), unionInfo.getUnionUid(), true, value, oldContribution, unionMember.getContribution(), son));
            }
            return value;
        }
        return 0;
    }

    public static long removeContribution(long value, CrossUnionInfo unionInfo, CrossUnionMember member, int son) {
        if (value > 0) {
            if (member != null && member.getContribution() >= value) {
                long oldContribution = member.getContribution();
                member.setContribution(member.getContribution() - value);
                syncUnionMember(member);
                CrossAutoLogMgr.add(new LogUnionContribution(member.getUserId(), unionInfo.getUnionUid(), false, value, oldContribution, member.getContribution(), son));
                return value;
            }
        }
        return 0;
    }

    /**
     * 下发member
     */
    public static void syncUnionMember(CrossUnionMember unionMember){
        UnionProto.UnionMemberTempMsg.Builder msg = CrossUnionPb.parseUnionMemberTempMsg(unionMember);
        if(null != msg){
            MessageHelper.sendPacket(unionMember.getServerId(), unionMember.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_UNION_MEMBER_SYNC, msg));
        }
    }

    /**
     * 获得新的会旗
     * 返还是否添加成功
     * @param unionId
     * @param flagId
     */
    public static boolean addUnionFlag(String unionId, int flagId) {
        UnionInfo unionInfo = getUnionInfo(unionId);
        if (unionInfo == null || unionInfo.isDelete()) {
            return false;
        }
        synchronized (unionFlagMap) {
            Map<Integer, CrossUnionFlag> flagMap = unionFlagMap.get(unionId);
            if (flagMap == null) {
                flagMap = new ConcurrentHashMap<>();
                unionFlagMap.put(unionId, flagMap);
            }
            CrossUnionFlag flag = flagMap.get(flagId);
            if (flag == null) {
                flag = new CrossUnionFlag();
                flag.setUnionUid(unionId);
                flag.setFlagId(flagId);
                flag.setInsertOption();
                flagMap.put(flagId, flag);
            }
            if(GoodsMgr.isUnionFlagParts(flagId)){
                flag.setExpireTime(-1);
                if(flag.isInsertOption()){
                    flag.setRead(false);
                    return true;
                }
                return false;
            }
            if (isFlagExpired(flag)) {
                flag.setExpireTime(System.currentTimeMillis() + GoodsMgr.getUnionFlagDurationTime(flagId));
                flag.setRead(false);
            } else {
                flag.setExpireTime(flag.getExpireTime() + GoodsMgr.getUnionFlagDurationTime(flagId));
            }
            return true;
        }
    }

    public static boolean removeUnionFlag(String unionId, int flagId) {
        UnionInfo unionInfo = getUnionInfo(unionId);
        if (unionInfo == null || unionInfo.isDelete()) {
            return false;
        }
        synchronized (unionFlagMap) {
            Map<Integer, CrossUnionFlag> flagMap = unionFlagMap.get(unionId);
            if (flagMap == null) {
                flagMap = new ConcurrentHashMap<>();
                unionFlagMap.put(unionId, flagMap);
            }
            CrossUnionFlag flag = flagMap.get(flagId);
            if (flag == null) {
                return true;
            }
            if(GoodsMgr.isUnionFlagParts(flagId)){
                flag.setExpireTime(0);
                return true;
            }
            return true;
        }
    }

    //扣除道具的时候会回收旗帜，把装备的设置成默认的蓝色的
    public static boolean changeUnionFlagByRemove(String unionId,List<Integer> removeFlagList){
        CrossUnionInfo unionInfo = getUnionInfo(unionId);
        if (unionInfo == null || unionInfo.isDelete()) {
            return false;
        }
        List<Integer> flagPartList = StringUtils.stringToIntegerList(unionInfo.getUnionFlagStr(),StringUtils.SPLIT_SEPARATOR);
        for(int flagId : removeFlagList){
            if(flagPartList.contains(flagId)){
                unionInfo.setUnionFlag(1);
                unionInfo.setUnionFlagStr("");
                unionInfo.setFlagModifyTime(0);
                return true;
            }
        }
        return true;
    }

    public static boolean hasUnionFlag(String unionId, int flagId) {
        boolean hasFlag = ConfigMgr.hasUnionFlag(flagId);
        if (hasFlag) {
            return true;
        }
        Map<Integer, CrossUnionFlag> flagMap = unionFlagMap.get(unionId);
        if (flagMap == null) {
            return false;
        }
        CrossUnionFlag flag = flagMap.get(flagId);
        if (flag == null) {
            return false;
        }
        if (isFlagExpired(flag)) return false;
        return true;
    }

    /**
     * 会旗是否过期
     *
     * @param flag
     * @return
     */
    private static boolean isFlagExpired(CrossUnionFlag flag) {
        if(flag.getExpireTime() == -1){
            return false;
        }
        if (System.currentTimeMillis() > flag.getExpireTime()) {
            return true;
        }
        return false;
    }

    public static void checkUnionFlag() {
        for (Map.Entry<String, Map<Integer, CrossUnionFlag>> entry : new HashMap<>(unionFlagMap).entrySet()) {
            String unionId = entry.getKey();
            CrossUnionInfo unionInfo = getUnionInfo(unionId);
            if (unionInfo == null) {
                continue;
            }
            int curFlagId = unionInfo.getUnionFlag();
            boolean changeFlag = false;
            for (CrossUnionFlag flag : new ArrayList<>(entry.getValue().values())) {
                if (flag.getFlagId() == curFlagId && isFlagExpired(flag)) {
                    //如果是当前的会旗，并且过期了,设置为默认会旗
                    int preUnionFlag = unionInfo.getPreUnionFlag();
                    unionInfo.setUnionFlag(preUnionFlag);
                    logger.info("unionFlag {} expired, change to {}", curFlagId, preUnionFlag);
                    //增加联盟日志
                    CrossUnionNoticeMgr.addNotice(null, unionId, eUnionNoticeType.UnionModify.getValue(), "");
                    //RankMgr.changeUnionRank(unionInfo);
                    //UnionActivityMgr.changeUnionInfo(unionInfo);
                    changeFlag = true;
                }
            }
            if(changeFlag){
                sendUnionChangeBroadcast(eUnionSyncType.Normal.getValue(), unionInfo, null, null, 0);
            }
        }
    }

    //read
    public static Map<Long, CrossUnionMember> getUnionMemberMap(String unionUid) {
        return unionMemberMap.get(unionUid);
    }

    public static int getUnionMemberCount(String unionUid) {
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionUid);
        if (null != memberMap) {
            return memberMap.size();
        }
        return 0;
    }

    public static CrossUnionInfo getUnionInfo(String unionUid) {
        return unionInfoMap.get(unionUid);
    }

    public static CrossUnionMember getUnionMemberByUserId(long userId) {
        return allUnionMemberMap.get(userId);
    }

    public static CrossUnionMember getUnionMember(String unionUid, long userId) {
        if (!StringUtils.isNullOrEmpty(unionUid)) {
            Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionUid);
            if (null != memberMap) {
                return memberMap.get(userId);
            }
            return null;
        } else {
            return deleteUnionMemberMap.get(userId);
        }
    }

    private static List<CrossUnionFlag> getUnionFlagList(String unionUid) {
        List<CrossUnionFlag> list = new ArrayList<>();
        Map<Integer, CrossUnionFlag> flagMap = unionFlagMap.get(unionUid);
        if (flagMap != null) {
            for(CrossUnionFlag flag : flagMap.values()){
                if(!CrossUnionMgr.isFlagExpired(flag)){
                    list.add(flag);
                }
            }
//            list = new ArrayList<>(flagMap.values());
        }
        return list;
    }

    public static CrossUnionInfo searchUnion(long unionAliasId, Set<Long> serverSet) {
        for (Long serverId : serverSet) {
            List<CrossUnionInfo> unionInfoList = getUnionListByServerId(serverId);
            for (CrossUnionInfo unionInfo : unionInfoList) {
                if (unionInfo.isDelete()) {
                    continue;
                }
                if (unionInfo.getUnionAliasId() == unionAliasId) {
                    return unionInfo;
                }
            }
        }
        return null;
    }

    /**
     * 获取议事厅门客总赚速
     * @param unionInfo
     * @return
     */
    public static long getChamberPatronsTotalEarnSpeed(UnionInfo unionInfo){
        long totalEarnSpeed = 0;
        if(unionInfo == null){
            return totalEarnSpeed;
        }
        Map<Long, CrossUnionMember> unionMemberMap = getUnionMemberMap(unionInfo.getUnionUid());
        if(unionMemberMap == null){
            return totalEarnSpeed;
        }
        for(CrossUnionMember item : unionMemberMap.values()){
            if(item.getChamberPatrons() != null){
                totalEarnSpeed += item.getChamberPatrons().getAbility().longValue();
            }
        }
        return totalEarnSpeed;
    }

    /**
     * 获取下一个商会别名编号
     */
    public static long getNextUnionAliasId() {
        return maxUnionAliasId.incrementAndGet();
    }

    public static int isCanRewardConstruct(UnionInfo unionInfo, UnionMember unionMember, int constructActive){
        if (unionMember.hasConstructRewardIndex(constructActive)) {
            return GameErrorCode.E_UNION_HAS_GET_CONSTRUCT_ACTIVE_REWARD;
        }
        if (unionInfo.getConstructActive() < constructActive) {
            return GameErrorCode.E_UNION_CONSTRUCT_ACTIVE_NO_ENOUGH;
        }
        return 0;
    }

    /**
     * 是否达到每日加入限制
     */
    private static boolean isDayJoinNumLimit(CrossUnionInfo unionInfo) {
        //是否已开启限制
        ServerInfo serverInfo = ServerListMgr.getServerInfo(unionInfo.getServerId());
        int days = DateHelper.calc2DateTDOADays(new Date(serverInfo.getOpenTime() * 1000), new Date());
        if(days < GameConfig.UNION_PER_DAY_JOIN_NUM_LIMIT_OPEN_TIME){
            return false;
        }
        if(unionInfo.getDayJoinNum() >= GameConfig.UNION_PER_DAY_JOIN_NUM_LIMIT){
            return true;
        }
        return false;
    }

    public static boolean checkUnionNameSame(String unionName) {
        for (UnionInfo unionInfo : unionInfoMap.values()) {
            if (!unionInfo.isDelete() && Objects.equals(unionInfo.getUnionName(), unionName)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 发送分组内所有商会信息到区服
     */
    public static CrossUnionProto.RequestCrossUnionDataRespMsg.Builder sendAllUnionGroupData(long serverId) {
        CrossUnionProto.RequestCrossUnionDataRespMsg.Builder respMsg = CrossUnionProto.RequestCrossUnionDataRespMsg.newBuilder();
        int groupId = CrossUnionServerGroupMgr.getGroupIdByServerId(serverId);
        Set<Long> serverSet = CrossUnionServerGroupMgr.getGroupServer(groupId);

        List<CrossUnionInfo> unionListInSameGroup = getUnionListInSameGroup(serverId);

        Map<Long, CrossUnionMember> allMemberList = new HashMap<>();
        for (Map.Entry<Long, CrossUnionMember> entry : deleteUnionMemberMap.entrySet()) {
            if(serverSet.contains(entry.getValue().getServerId())){
                allMemberList.put(entry.getKey(), entry.getValue());
            }
        }

        for (CrossUnionInfo crossUnionInfo : unionListInSameGroup) {
            respMsg.addAllUnion(getCrossUnionTemp(crossUnionInfo));

            Map<Long, CrossUnionMember> memberMap = unionMemberMap.get(crossUnionInfo.getUnionUid());
            if(memberMap != null){
                allMemberList.putAll(memberMap);
            }
        }

        for (Map.Entry<Long, CrossUnionMember> entry : allMemberList.entrySet()) {
            respMsg.addAllMember(CrossUnionPb.buildCrossUnionMemberTemp(entry.getValue()));
        }

        return respMsg;
    }

    /**
     * 是否有审批通过的权限
     */
    public static boolean hasApplyPassRole(CrossUnionMember member) {
        if(member == null){
            return false;
        }
        return member.getPosition() == eUnionPosition.Master.getValue() || member.getPosition() == eUnionPosition.DeputyMaster.getValue();
    }

    //set get

    public static Map<String, CrossUnionInfo> getUnionInfoMap() {
        return unionInfoMap;
    }

    public static Map<String, CrossUnionInfo> getDeleteUnionInfoMap() {
        return deleteUnionInfoMap;
    }

    public static void setDeleteUnionInfoMap(Map<String, CrossUnionInfo> deleteUnionInfoMap) {
        CrossUnionMgr.deleteUnionInfoMap = deleteUnionInfoMap;
    }

    public static Map<String, Map<Long, CrossUnionMember>> getUnionMemberMap() {
        return unionMemberMap;
    }

    public static void setUnionMemberMap(Map<String, Map<Long, CrossUnionMember>> unionMemberMap) {
        CrossUnionMgr.unionMemberMap = unionMemberMap;
    }

    public static Map<Long, CrossUnionMember> getDeleteUnionMemberMap() {
        return deleteUnionMemberMap;
    }

    public static void setDeleteUnionMemberMap(Map<Long, CrossUnionMember> deleteUnionMemberMap) {
        CrossUnionMgr.deleteUnionMemberMap = deleteUnionMemberMap;
    }

    //pb
    public static UnionProto.UnionDetailMsg.Builder getUnionDetailMsg(String unionUid, int syncType) {
        if(StringUtils.isNullOrEmpty(unionUid)){
            return CrossUnionPb.parseUnionDetailMsg("", null, null, syncType, null);
        }
        CrossUnionInfo unionInfo = getUnionInfo(unionUid);
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionUid);
        List<CrossUnionMember> memberList = null;
        if (null != memberMap) {
            memberList = new ArrayList<>(memberMap.values());
        }
        List<CrossUnionFlag> flagList = getUnionFlagList(unionUid);
        return CrossUnionPb.parseUnionDetailMsg(unionUid, unionInfo, memberList, syncType, flagList).addAllMemberGrade(getMemberRankGradeMsg(unionInfo));
    }

    public static UnionProto.UnionDetailMsg.Builder getUnionDetailMsg(CrossUnionInfo unionInfo, int syncType) {
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionInfo.getUnionUid());
        List<CrossUnionMember> memberList = null;
        if (null != memberMap) {
            memberList = new ArrayList<>(memberMap.values());
        }
        List<CrossUnionFlag> flagList = getUnionFlagList(unionInfo.getUnionUid());
        return CrossUnionPb.parseUnionDetailMsg(unionInfo.getUnionUid(), unionInfo, memberList, syncType, flagList).addAllMemberGrade(getMemberRankGradeMsg(unionInfo));
    }

    public static CrossUnionProto.CrossUnionTemp.Builder getCrossUnionTemp(CrossUnionInfo unionInfo){
        CrossUnionProto.CrossUnionTemp.Builder builder = CrossUnionPb.buildCrossUnionTemp(unionInfo);
        List<CrossUnionFlag> flagList = getUnionFlagList(unionInfo.getUnionUid());
        for (CrossUnionFlag unionFlag : flagList) {
            if(unionFlag.getFlagId() > 1000){
                builder.addAllUnionFlag(unionFlag.getFlagId());
            }
        }
        return builder;
    }


    public static void notifyAllMemberChamberChange(String unionUid, long userId, boolean isRemove, CrossUnionChamberPatrons newPatrons) {
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionUid);
        if (null != memberMap) {
            UnionProto.UnionChamberPatronsListMsg.Builder listMsg = UnionProto.UnionChamberPatronsListMsg.newBuilder();
            if (isRemove) {
                UnionProto.UnionChamberPatronsTempMsg.Builder msg = CrossUnionPb.parseCrossUnionChamberPatronsTempMsg(userId, true, null);
                listMsg.addDataList(msg);
            } else {
                UnionProto.UnionChamberPatronsTempMsg.Builder msg = CrossUnionPb.parseCrossUnionChamberPatronsTempMsg(userId, false, newPatrons);
                listMsg.addDataList(msg);
            }
            for (CrossUnionMember member : memberMap.values()) {
                MessageHelper.sendPacket(member.getServerId(), member.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_UNION_CHAMBER_PATRONS_SYNC, listMsg));
            }
        }
    }

    //
    public static void sendUnionChangeBroadcast(int syncType, CrossUnionInfo unionInfo, CrossUserBaseInfo player, Map<Long, CrossUnionMember> memberMap, long targetId) {
        CrossUnionProto.CrossUnionChangeBroadcastMsg.Builder broadcast = CrossUnionProto.CrossUnionChangeBroadcastMsg.newBuilder();
        broadcast.setSyncType(syncType);
        if(player != null) {
            broadcast.setPlayerId(player.getUserId());
        }else {
            broadcast.setPlayerId(0);
        }
        int groupId = CrossUnionServerGroupMgr.getGroupIdByServerId(unionInfo.getServerId());
        Set<Long> serverIdSet = CrossUnionServerGroupMgr.getGroupServer(groupId);
        if(syncType == eUnionSyncType.DeleteUnion.getValue()){
            if (memberMap != null) {
                for (Map.Entry<Long, CrossUnionMember> entry : memberMap.entrySet()) {
                    broadcast.addMember(CrossUnionPb.buildCrossUnionMemberTemp(entry.getValue()));
                }
            }
        }else {
            Map<Long, CrossUnionMember> map = getUnionMemberMap(unionInfo.getUnionUid());
            if(map != null){
                for (Map.Entry<Long, CrossUnionMember> entry : map.entrySet()) {
                    broadcast.addMember(CrossUnionPb.buildCrossUnionMemberTemp(entry.getValue()));
                }
            }
            if(syncType == eUnionSyncType.BeKick.getValue() || syncType == eUnionSyncType.QuitUnion.getValue()){
                CrossUnionMember member = CrossUnionMgr.getUnionMember("", targetId);
                if(member != null){
                    broadcast.setChangeMember(CrossUnionPb.buildCrossUnionMemberTemp(member));
                }
            }else if(syncType == eUnionSyncType.CreateUnion.getValue() || syncType == eUnionSyncType.JoinUnion.getValue()){
                CrossUnionMember member = CrossUnionMgr.getUnionMember(unionInfo.getUnionUid(), targetId);
                if(member != null){
                    broadcast.setChangeMember(CrossUnionPb.buildCrossUnionMemberTemp(member));
                }
            }else if(syncType == eUnionSyncType.SetPosition.getValue()){
                CrossUnionMember member = CrossUnionMgr.getUnionMember(unionInfo.getUnionUid(), targetId);
                if(member != null){
                    broadcast.setChangeMember(CrossUnionPb.buildCrossUnionMemberTemp(member));
                }
            }
        }

        broadcast.setMsg(getUnionDetailMsg(unionInfo, syncType));
        broadcast.setUnion(getCrossUnionTemp(unionInfo));

        for (long serverId : serverIdSet) {
            MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(Protocol.S_CROSS_UNION_BROADCAST_FROM_CROSS, broadcast));
        }
    }

    private static Set<Long> getUnionServerIdSet(String unionUid) {
        Set<Long> serverIdSet = new HashSet<>();
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap().get(unionUid);
        if (memberMap != null) {
            for (Map.Entry<Long, CrossUnionMember> entry : memberMap.entrySet()) {
                serverIdSet.add(entry.getValue().getServerId());
            }
        }
        return serverIdSet;
    }

    public static UnionBaseInfo parseUnionBaseInfo(CrossUnionInfo unionInfo){
        UnionBaseInfo baseInfo = new UnionBaseInfo();
        baseInfo.setUnionAliasId(unionInfo.getUnionAliasId());
        baseInfo.setUnionName(unionInfo.getUnionName());
        baseInfo.setUnionFlag(unionInfo.getUnionFlag());
        baseInfo.setExperience(unionInfo.getExperience());
        baseInfo.setMemberCount(unionInfo.getMemberCount());
        baseInfo.setAllowRandomJoin(unionInfo.isAllowRandomJoin());
        baseInfo.setTotalEarnSpeed(unionInfo.getTotalEarnSpeed());
        baseInfo.setTotalPatronsAbility(unionInfo.getTotalMaxAbility());
        baseInfo.setMasterUserId(unionInfo.getMasterUserId());
        baseInfo.setMasterNickName(unionInfo.getMasterNickName());
        baseInfo.setMasterVipExp(unionInfo.getVipExp());
        baseInfo.setMasterDecoration(unionInfo.getDecoration());
        baseInfo.setServerId(unionInfo.getServerId());
        baseInfo.setCross(unionInfo.isCross());
        baseInfo.setUnionFlagStr(unionInfo.getUnionFlagStr());
        baseInfo.setHonors(unionInfo.getHonors());
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionInfo.getUnionUid());
        if (memberMap != null) {
            Map<Long, CrossUnionMember> unionMemberMap = new HashMap<>(memberMap);
            for (CrossUnionMember unionMember : unionMemberMap.values()) {
                if (unionMember.getPosition() == eUnionPosition.Master.getValue()) {
                    UserBaseInfo userBaseInfo = unionMember.getUserBaseInfo();
                    baseInfo.setHideVipAndAddress(userBaseInfo.getHideVipAndAddress());
                    baseInfo.setSex(userBaseInfo.getSex());
                    baseInfo.setMasterVipExp(userBaseInfo.getVipExp());
                    baseInfo.setMasterNickName(userBaseInfo.getNickName());
                    baseInfo.setMasterDecoration(userBaseInfo.getDecoration());
                }
            }
        }

        return baseInfo;
    }

    public static void checkCoolingOffTimeNotice(CrossUnionMember member) {
        //冷静期开启后每日首次进入商会界面均推送“冷静期”公告
        if (null != member && !member.getDayCoolingOffNotice()) {
            CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(member.getUnionUid());
            long nowTime = System.currentTimeMillis() / 1000;
            if (null != unionInfo && nowTime < unionInfo.getDeleteCoolingOffTime() + GameConfig.UNION_DELETE_COOLING_OFF_CD) {
                member.setDayCoolingOffNotice(true);
                UnionProto.DeleteCoolingOffNoticeMsg.Builder msg = UnionProto.DeleteCoolingOffNoticeMsg.newBuilder();
                msg.setDeleteCoolingOffTime(unionInfo.getDeleteCoolingOffTime());
                MessageHelper.sendPacket(member.getServerId(), member.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_UNION_DELETE_COOLINGOFF_NOTICE, msg));
            }
        }
    }

    /**
     * 小玉用一键商会副业经营
     * @param serverId
     * @param playerId
     * @param unionUid
     * @return
     */
    public static UnionParergonOperateResult assistantParergonOperate(long serverId, long playerId, String unionUid) {
        UnionParergonPlayer parergonPlayer = CrossUnionParergonMgr.getParergonPlayer(playerId);
        CrossUnionParergonMgr.calOperateTimes(parergonPlayer);
        UnionParergonOperateResult finalResult = null;

        UnionParergon parergon = CrossUnionParergonMgr.getParergon(unionUid);
        //最后一次经营的副业
        int lastOperateParergonId = 0;
        //写成while防止以后一次一键经营次数可能完成两次副业
        while (parergon.getParergonId() != lastOperateParergonId) {
            //商会当前副业
            lastOperateParergonId = parergon.getParergonId();
            UnionParergonOperateResult onceResult = CrossUnionMgr.parergonOperate(serverId, playerId, parergon.getParergonId(), 1, 0);
            //第一次进行
            if (finalResult == null) {
                // 如果有错误码直接返回
                if (onceResult.getRet() != 0) {
                    return onceResult;
                }
                // 否则将最后结果赋值第一次结果,开始下一轮判断
                finalResult = onceResult;
            } else {
                //第二次及以后 有错误码直接返回最后的成功消息
                if (onceResult.getRet() != 0) {
                    return finalResult;
                }
                finalResult = mergeAssistantUnionParergonOperateResult(finalResult, onceResult);
            }
        }
        // 如果副业信息出错没出结果
        if (finalResult == null) {
            finalResult = new UnionParergonOperateResult();
            finalResult.setRet(GameErrorCode.E_PARERGON_NET_FIND);
        }
        return finalResult;
    }

    /**
     * 合并两次副业一键经营结果
     * @param oldResult
     * @param newResult
     * @return
     */
    public static UnionParergonOperateResult mergeAssistantUnionParergonOperateResult(UnionParergonOperateResult oldResult, UnionParergonOperateResult newResult) {
        if (newResult.getRet() != 0) {
            return oldResult;
        } else {
            //主要保证次数和总银两
            UnionParergonOperateResult unionParergonOperateResult = new UnionParergonOperateResult();
            unionParergonOperateResult.setAddSilver(oldResult.getAddSilver().add(newResult.getAddSilver()));
            unionParergonOperateResult.setParergonId(newResult.getParergonId());
            unionParergonOperateResult.setFinish(newResult.isFinish());
            unionParergonOperateResult.setFindBusinessman(oldResult.isFindBusinessman() || newResult.isFindBusinessman());
            unionParergonOperateResult.setOperateTimes(newResult.getOperateTimes());
            unionParergonOperateResult.setLastRestoreTime(newResult.getLastRestoreTime());
            unionParergonOperateResult.setFinishTimes(oldResult.getFinishTimes() + newResult.getFinishTimes());
            unionParergonOperateResult.setHistoryTimes(newResult.getHistoryTimes());
            unionParergonOperateResult.setProgress(newResult.getProgress());
            return unionParergonOperateResult;
        }
    }

    public static CrossUnionProto.CrossUnionGetMaxAbilityUnionRankListResp.Builder getTopMaxAbilityUnionListMsg(int activityId, List<Long> serverIds, int topCount) {
        CrossUnionProto.CrossUnionGetMaxAbilityUnionRankListResp.Builder rankMsg = CrossUnionProto.CrossUnionGetMaxAbilityUnionRankListResp.newBuilder();
        rankMsg.setActivityId(activityId);
        rankMsg.setUpdateTime(DateHelper.getCurrentTime());

        List<CrossUnionInfo> unionListByServerList = getUnionListByServerList(serverIds);

        List<CrossUnionInfo> unionInfos = new ArrayList<>();
        for (CrossUnionInfo unionInfo : unionListByServerList) {
            if(unionInfo.isDelete()){
                continue;
            }
            if (!serverIds.contains(unionInfo.getServerId())) {
                continue;
            }

            BigInteger totalAbility = BigInteger.ZERO;
            Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionInfo.getUnionUid());
            for (CrossUnionMember crossUnionMember : memberMap.values()) {
                totalAbility = totalAbility.add(crossUnionMember.getHistoryMaxAbility());
            }
            unionInfo.setTotalMaxAbility(totalAbility);
            unionInfos.add(unionInfo);
        }
        unionInfos.sort((o1, o2) -> {
            return o2.getTotalMaxAbility().compareTo(o1.getTotalMaxAbility());
        });

        for (int i = 0; i < topCount && i < unionInfos.size(); i++) {
            CrossUnionInfo unionInfo = unionInfos.get(i);
            CrossUnionProto.CrossUnionActivityLockRankTemp.Builder tempMsg = CrossUnionProto.CrossUnionActivityLockRankTemp.newBuilder();
            tempMsg.setUnionUid(unionInfo.getUnionUid());
            tempMsg.setUnionBase(UnionBasePb.parseUnionBaseTempMsg(parseUnionBaseInfo(unionInfo)));
            tempMsg.setTotalAbility(unionInfo.getTotalMaxAbility().toString());

            CrossUnionProto.UnionMemberIdsTemp.Builder memberMsg = CrossUnionProto.UnionMemberIdsTemp.newBuilder();
            memberMsg.setUnionId(unionInfo.getUnionUid());
            Map<Long, CrossUnionMember> members = getUnionMemberMap(unionInfo.getUnionUid());
            if (null != members && !members.isEmpty()) {
                for (CrossUnionMember member : members.values()) {
                    CrossUnionProto.UnionMemberTemp.Builder memberBuilder = CrossUnionProto.UnionMemberTemp.newBuilder();
                    memberBuilder.setUserId(member.getUserId()).setServerid(member.getServerId());
                    memberBuilder.setPosition(member.getPosition());
                    UserBaseInfo userBaseInfo = member.getUserBaseInfo();
                    memberBuilder.setEarnSpeed(userBaseInfo.getEarnSpeed().toString());
                    memberBuilder.setMaxAbility(member.getHistoryMaxAbility().toString());
                    memberMsg.addMemberIds(memberBuilder);
                }
            }
            rankMsg.addRank(tempMsg);
            rankMsg.addUnionMemberIs(memberMsg);
        }

        return rankMsg;
    }

    public static CrossUnionProto.ChannelGetUnionMaxAbilityRankListResp.Builder getCTopMaxAbilityUnionListMsg(int activityId, int channelId,List<Long> serverIds, int topCount) {
        CrossUnionProto.ChannelGetUnionMaxAbilityRankListResp.Builder rankMsg = CrossUnionProto.ChannelGetUnionMaxAbilityRankListResp.newBuilder();
        rankMsg.setActivityId(activityId);
        rankMsg.setChannel(channelId);
        List<CrossUnionInfo> unionListByServerList = getUnionListByServerList(serverIds);
        List<CrossUnionInfo> unionInfos = new ArrayList<>();
        for (CrossUnionInfo unionInfo : unionListByServerList) {
            if(unionInfo.isDelete()){
                continue;
            }
            if (!serverIds.contains(unionInfo.getServerId())) {
                continue;
            }

            BigInteger totalAbility = BigInteger.ZERO;
            Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionInfo.getUnionUid());
            for (CrossUnionMember crossUnionMember : memberMap.values()) {
                totalAbility = totalAbility.add(crossUnionMember.getHistoryMaxAbility());
            }
            unionInfo.setTotalMaxAbility(totalAbility);
            unionInfos.add(unionInfo);
        }
        unionInfos.sort((o1, o2) -> {
            return o2.getTotalMaxAbility().compareTo(o1.getTotalMaxAbility());
        });

        for (int i = 0; i < topCount && i < unionInfos.size(); i++) {
            CrossUnionInfo unionInfo = unionInfos.get(i);
            CrossUnionProto.ChannelUnionActivityLockRankTemp.Builder tempMsg = CrossUnionProto.ChannelUnionActivityLockRankTemp.newBuilder();
            tempMsg.setUnionUid(unionInfo.getUnionUid());
            tempMsg.setUnionBase(UnionBasePb.parseUnionBaseTempMsg(parseUnionBaseInfo(unionInfo)));
            tempMsg.setTotalAbility(unionInfo.getTotalMaxAbility().toString());

            CrossUnionProto.ChannelUnionMemberListTemp.Builder memberMsg = CrossUnionProto.ChannelUnionMemberListTemp.newBuilder();
            memberMsg.setUnionId(unionInfo.getUnionUid());
            Map<Long, CrossUnionMember> members = getUnionMemberMap(unionInfo.getUnionUid());
            if (null != members && !members.isEmpty()) {
                for (CrossUnionMember member : members.values()) {
                    CrossUnionProto.ChannelUnionMemberTemp.Builder memTempMsg = CrossUnionProto.ChannelUnionMemberTemp.newBuilder();
                    memTempMsg.setUserId(member.getUserId());
                    memTempMsg.setServerId(member.getServerId());
                    memTempMsg.setPosition(member.getPosition());
                    memTempMsg.setAbility(member.getHistoryMaxAbility().toString());
                    memberMsg.addMembers(memTempMsg);
                }
            }
            rankMsg.addRank(tempMsg);
            rankMsg.addUnionMembers(memberMsg);
        }

        return rankMsg;
    }

    public static CrossUnionProto.CrossUnionGetMaxAbilityUnionRankListResp.Builder getTopMaxAbilityUnionListMsgByUnionIds(int activityId, List<String> unionIds, int topCount, int groupId) {
        CrossUnionProto.CrossUnionGetMaxAbilityUnionRankListResp.Builder rankMsg = CrossUnionProto.CrossUnionGetMaxAbilityUnionRankListResp.newBuilder();
        rankMsg.setActivityId(activityId);
        rankMsg.setUpdateTime(DateHelper.getCurrentTime());
        rankMsg.setGroupId(groupId);
        List<CrossUnionInfo> unionInfos = new ArrayList<>();
        for (String unionId : unionIds) {
            CrossUnionInfo unionInfo = getUnionInfo(unionId);
            if (unionInfo == null) {
                continue;
            }
            if(unionInfo.isDelete()){
                continue;
            }

            BigInteger totalAbility = BigInteger.ZERO;
            UnionActivityGroupUnion unionData = Cross3UnionActivityGroupMgr.getUnionData(activityId, unionId, groupId);
            if (unionData != null) {
                for (Long memberId : unionData.getUserMap().keySet()) {
                    CrossUnionMember crossUnionMember = getUnionMemberByUserId(memberId);
                    if (crossUnionMember != null) {
                        totalAbility = totalAbility.add(crossUnionMember.getHistoryMaxAbility());
                    }
                }
            }

            unionInfo.setTotalMaxAbility(totalAbility);
            unionInfos.add(unionInfo);
        }

        unionInfos.sort((o1, o2) -> {
            return o2.getTotalMaxAbility().compareTo(o1.getTotalMaxAbility());
        });

        for (int i = 0; i < topCount && i < unionInfos.size(); i++) {
            CrossUnionInfo unionInfo = unionInfos.get(i);
            CrossUnionProto.CrossUnionActivityLockRankTemp.Builder tempMsg = CrossUnionProto.CrossUnionActivityLockRankTemp.newBuilder();
            tempMsg.setUnionUid(unionInfo.getUnionUid());
            tempMsg.setUnionBase(UnionBasePb.parseUnionBaseTempMsg(parseUnionBaseInfo(unionInfo)));
            tempMsg.setTotalAbility(unionInfo.getTotalMaxAbility().toString());

            CrossUnionProto.UnionMemberIdsTemp.Builder memberMsg = CrossUnionProto.UnionMemberIdsTemp.newBuilder();
            memberMsg.setUnionId(unionInfo.getUnionUid());
            UnionActivityGroupUnion unionData = Cross3UnionActivityGroupMgr.getUnionData(activityId, unionInfo.getUnionUid(), groupId);
            if (unionData != null) {
                for (Long memberId : unionData.getUserMap().keySet()) {
                    CrossUnionMember member = getUnionMemberByUserId(memberId);
                    if (member != null) {
                        CrossUnionProto.UnionMemberTemp.Builder memberBuilder = CrossUnionProto.UnionMemberTemp.newBuilder();
                        memberBuilder.setUserId(member.getUserId()).setServerid(member.getServerId());
                        memberBuilder.setPosition(member.getPosition());
                        UserBaseInfo userBaseInfo = member.getUserBaseInfo();
                        memberBuilder.setEarnSpeed(userBaseInfo.getEarnSpeed().toString());
                        memberBuilder.setMaxAbility(member.getHistoryMaxAbility().toString());
                        memberMsg.addMemberIds(memberBuilder);
                    }
                }
            }
            rankMsg.addRank(tempMsg);
            rankMsg.addUnionMemberIs(memberMsg);
        }

        return rankMsg;
    }

    /**
     * 获得商会里指定实力的人数
     */
    public static int getUnionMemberCountByRankGrade(CrossUnionInfo unionInfo, int rankGrade) {
        String unionId = unionInfo.getUnionUid();
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionId);
        if (null == memberMap) {
            return 0;
        }
        CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroupByServerId(unionInfo.getServerId());
        if (null == serverGroup || serverGroup.getState() == 0) {
            return 0;
        }
        int amount = 0;
        for (CrossUnionMember member : memberMap.values()) {
            int memberRankGrade = member.getAbilityRankGrade();
            if (rankGrade == memberRankGrade) {
                amount++;
            }
        }
        return amount;
    }

    /**
     * 获得商会里非最后一档的人数和
     */
    public static int getUnionMemberCountExceptLastGrade(CrossUnionInfo unionInfo, int lastGrade) {
        String unionId = unionInfo.getUnionUid();
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionId);
        if (null == memberMap) {
            return 0;
        }
        CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroupByServerId(unionInfo.getServerId());
        if (null == serverGroup || serverGroup.getState() == 0) {
            return 0;
        }
        int amount = 0;
        for (CrossUnionMember member : memberMap.values()) {
            int memberRankGrade = member.getAbilityRankGrade();
            if (0 == memberRankGrade){
                continue;
            }
            if (lastGrade != memberRankGrade) {
                amount++;
            }
        }
        return amount;
    }

    /**
     * 判断实力档位人数满了没,是否可以加入
     */
    public static boolean canJoinUnionByAbilityGrade(CrossUnionInfo unionInfo, long serverId, long userId) {
        if (null == unionInfo) {
            return false;
        }

        CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroupByServerId(serverId);
        if (null == serverGroup || serverGroup.getState() == 0) {
            return true;
        }
        int rankGrade = 0;
        CrossUnionMember member = getUnionMemberByUserId(userId);
        if (null == member) {
            return true;
        }
        rankGrade = member.getAbilityRankGrade();
        if (0 == rankGrade){
            return true;
        }

        int lastGrade = ConfigMgr.getLastMonthAbilityRankGrade();
        if (rankGrade == lastGrade) {//最后一档没有限制
            return true;
        }

        int rankGradeAmount = getUnionMemberCountByRankGrade(unionInfo, rankGrade);
        int numLimit = unionInfo.getJoinGradeLimit().getOrDefault(rankGrade, 0);
        if (rankGradeAmount >= numLimit) {
            return false;
        }

        //实际限制
        int totalLimit = unionInfo.getGradeRankTotalLimit();
        if (0 == totalLimit){
            totalLimit = getRankGradeTotalLimit(unionInfo);
            unionInfo.setGradeRankTotalLimit(totalLimit);
        }

        int amountHave = getUnionMemberCountExceptLastGrade(unionInfo, lastGrade);
        if (amountHave >= totalLimit) {
            return false;
        }

        return true;
    }

    /**
     * 获得实力评定实际总人数限制
     */
    public static int getRankGradeTotalLimit(CrossUnionInfo unionInfo) {
        int lastGrade = ConfigMgr.getLastMonthAbilityRankGrade();
        //非最后一档的总人数限制
        //配置的限制
        int configLimitAmount = 0;
        for (Map.Entry<Integer, Integer> gradeEntry : ConfigMgr.getCrossUnionJoinNumLimitByAbilityGrade().entrySet()) {
            if (gradeEntry.getKey() != lastGrade) {
                configLimitAmount += gradeEntry.getValue();
            }
        }

        //实力评定时的限制
        int gradeLimitAmount = 0;
        for (Map.Entry<Integer, Integer> gradeEntry : unionInfo.getGradeAmountMap().entrySet()) {
            if (gradeEntry.getKey() != lastGrade) {
                gradeLimitAmount += gradeEntry.getValue();
            }
        }

        //实际限制
        int totalLimit = Math.max(configLimitAmount, gradeLimitAmount);
        return totalLimit;
    }

    /**
     * @param unionInfo
     * @return k:grade v:num
     */
    public static Map<Integer, Integer> getMemberRankGradeMap(CrossUnionInfo unionInfo) {
        Map<Integer, Integer> gradeNumMab = new ConcurrentHashMap<>();
        String unionId = unionInfo.getUnionUid();
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionId);
        if (null == memberMap) {
            return gradeNumMab;
        }
        CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroupByServerId(unionInfo.getServerId());
        if (null == serverGroup || serverGroup.getState() == 0) {
            return gradeNumMab;
        }
        for (CrossUnionMember member : memberMap.values()) {
            int memberRankGrade = member.getAbilityRankGrade();
            if (0 == memberRankGrade) {
                continue;
            }
            int amount = gradeNumMab.getOrDefault(memberRankGrade, 0);
            amount++;
            gradeNumMab.put(memberRankGrade, amount);
        }

        return gradeNumMab;
    }

    public static List<UnionProto.UnionMemberRankGradeTemp> getMemberRankGradeMsg(CrossUnionInfo unionInfo) {
        List<UnionProto.UnionMemberRankGradeTemp> msgList = new ArrayList<>();
        Map<Integer, Integer> gradeNumMab = getMemberRankGradeMap(unionInfo);
        for (Map.Entry<Integer, Integer> entry : unionInfo.getJoinGradeLimit().entrySet()) {
            int grade = entry.getKey();
            int numLimit = entry.getValue();
            int numHave = gradeNumMab.getOrDefault(grade, 0);
            msgList.add(UnionProto.UnionMemberRankGradeTemp.newBuilder().setGradeId(grade).setNumHave(numHave).setNumLmit(numLimit).build());
        }

        return msgList;
    }

    public static void updateMemberMonthRank(int groupId) {
        CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroup(groupId);
        if (null == serverGroup) {
            return;
        }
        Set<Long> serverSet = new ConcurrentHashSet<>(serverGroup.getServerList());
        List<CrossUnionMember> memberList = new ArrayList<>(allUnionMemberMap.values());
        CrossGroupMonthRankListModel rankModel = CrossGroupUserMonthAbilityRankMgr.getCrossGroupRankListModelMap(groupId, DateHelper.getMonth(), false);
        if (null == rankModel) {
            return;
        }

        //重置段位
        for (CrossUnionMember member : memberList) {
            if (!serverSet.contains(member.getServerId())) {
                continue;
            }
            member.setMonthAbilityRank(-1);
            member.setAbilityRankGrade(0);
        }

        //设置段位
        for (CrossUserRank crossUserRank : rankModel.getRankList()) {
            CrossUnionMember member = getUnionMemberByUserId(crossUserRank.getUserId());
            if (null != member){
                member.setMonthAbilityRank(crossUserRank.getRank());
                member.setAbilityRankGrade(Integer.valueOf(crossUserRank.getParam()));
                uploadDataAnalytics(groupId, DateHelper.getMonth(), crossUserRank, member);
            }
        }

        //设置名额限制
        for (String unionId : unionMemberMap.keySet()) {
            CrossUnionInfo unionInfo = getUnionInfo(unionId);
            if (null == unionInfo || unionInfo.isDelete() || !serverSet.contains(unionInfo.getServerId())) {
                continue;
            }

            //若商会在评定时，商会某个评级的人数＞配置的资格名额，则该商会本月该评级的名额人数=商会实际的该评级人数
            unionInfo.setGradeAmountMap(getMemberRankGradeMap(unionInfo));
            unionInfo.setJoinGradeLimit(getNewJoinLimitMap(unionInfo));
            unionInfo.setGradeRankTotalLimit(0);
        }

        CrossDataAnalyticsMgr.provider.flush();
    }

    private static void uploadDataAnalytics(int groupId, int month, CrossUserRank crossUserRank, CrossUnionMember member) {
        //上报数数,掌柜以上
        if(member.getAbilityRankGrade() >= 5){
            return;
        }
        if(!CrossDataAnalyticsMgr.openDataAnalytics()){
            return;
        }

        try{
            DataBuilder dataBuilder = DataBuilder.newBuilder(member.getUserId(), "");
            dataBuilder.build("resources_group", groupId);
            dataBuilder.build("resources_month", month);
            dataBuilder.build("resources_rankid", crossUserRank.getRank());
            dataBuilder.build("resources_rankvalue", crossUserRank.getValue().toString());
            dataBuilder.build("resources_id", member.getAbilityRankGrade());
            CrossDataAnalyticsMgr.provider.track(dataBuilder.getAccountId(), dataBuilder.getDistinctId(), "resources_rank", dataBuilder.getDataMap());
        }catch (Exception e){
            getLogger().error("", e);
        }
    }

    private static Map<Integer, Integer> getNewJoinLimitMap(CrossUnionInfo unionInfo) {
        CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroupByServerId(unionInfo.getServerId());
        if (null == serverGroup || serverGroup.getState() == 0) {
            return new ConcurrentHashMap<>();
        }
        Map<Integer, Integer> newGradeLimitMab = new ConcurrentHashMap<>(unionInfo.getGradeAmountMap());
        Map<Integer, Integer> gradeLimitMap = ConfigMgr.getCrossUnionJoinNumLimitByAbilityGrade();
        for (Map.Entry<Integer, Integer> gradeEntry : gradeLimitMap.entrySet()) {
            int grade = gradeEntry.getKey();
            int numLimit = gradeEntry.getValue();
            if (newGradeLimitMab.containsKey(grade)) {
                if (numLimit > newGradeLimitMab.get(grade)) {
                    newGradeLimitMab.put(grade, numLimit);
                }
            } else {
                newGradeLimitMab.put(grade, numLimit);
            }
        }

        int lastGrade = ConfigMgr.getLastMonthAbilityRankGrade();
        if (!newGradeLimitMab.containsKey(lastGrade)) {
            newGradeLimitMab.put(lastGrade, 0);
        }
        return newGradeLimitMab;
    }

    /**
     * 修改加入限制，只能高往低调 最高档位=1
     *
     * @return
     */
    public static int changeRankGradeJoinLimit(CrossUnionInfo unionInfo, Map<Integer, Integer> newJoinLimit) {
        int lastGrade = ConfigMgr.getLastMonthAbilityRankGrade();
        Map<Integer, Integer> gradeNumMab = getMemberRankGradeMap(unionInfo);
        //从高档位取出来的名额
        int takeAmount = 0;
        for (int i = 1; i < lastGrade; i++) {
            //评定时的档位人数
            int originalHave = unionInfo.getGradeAmountMap().getOrDefault(i, 0);
            //当前档位人数
            int numHave = gradeNumMab.getOrDefault(i, 0);
            //设置的档位人数限制
            int newLimit = newJoinLimit.getOrDefault(i, 0);

//            if (0 == newLimit) {
//                return GameErrorCode.E_ERROR_DATA;
//            }
            if (newLimit < numHave) {//限制不能低于当前的
                return GameErrorCode.E_ERROR_DATA;
            }

            //评定时的限制
            int originalLimit = ConfigMgr.getCrossUnionJoinNumLimitByAbilityGrade(i);
            originalLimit = Math.max(originalHave, originalLimit);

            //名额只能从高往低借用
            if (originalLimit + takeAmount < newLimit) {
                return GameErrorCode.E_ERROR_DATA;
            } else {
                //名额取出来给下一档判断用
                takeAmount = originalLimit + takeAmount - newLimit;
            }
        }

        if (!newJoinLimit.containsKey(lastGrade)) {
            newJoinLimit.put(lastGrade, gradeNumMab.getOrDefault(lastGrade, 0));
        }

        unionInfo.setJoinGradeLimit(newJoinLimit);

        return 0;
    }

    /**
     * 检查玩家的实力评定段位,没有设置过档次的,从排行榜取一个档次;只有不活跃玩家上线才会没有档次
     */
    public static void checkUserMonthRankGrade(long serverId, long userId, BigInteger ability) {
        CrossUnionServerGroup serverGroup = CrossUnionServerGroupMgr.getServerGroupByServerId(serverId);
        if (null == serverGroup || serverGroup.getState() == 0) {
            return;
        }
        if (!CrossGroupUserMonthAbilityRankMgr.isServerGroupOver(serverId)) {
            return;
        }
        CrossUnionMember member = getUnionMemberByUserId(userId);
        if (null == member) {
            CrossUserBaseInfo userBaseInfo = CrossUserMgr.getCrossUserBaseInfo(userId);
            if (null != userBaseInfo) {
                member = createDeleteMember(userBaseInfo, serverId);
            }
        }

        if (null != member) {
            CrossUserRank crossUserRank = CrossGroupUserMonthAbilityRankMgr.getCrossUserRank(serverId, userId);
            if (null != crossUserRank && !StringUtils.isNullOrEmpty(crossUserRank.getParam())) {
                member.setMonthAbilityRank(crossUserRank.getRank());
                //在榜单上
                member.setAbilityRankGrade(Integer.valueOf(crossUserRank.getParam()));
            } else {
                int grade = CrossGroupUserMonthAbilityRankMgr.getUserRankGradeByAbility(serverId, ability);
                member.setAbilityRankGrade(grade);
            }
        }
    }

    /**
     * 实力评定缓存返回游戏服
     * @param serverId
     * @param userId
     */
    public static void syncGradeBack(long serverId, long userId){
        CrossUnionProto.SyncPlayerGradeMsg.Builder builder = CrossUnionProto.SyncPlayerGradeMsg.newBuilder();
        CrossUnionMember unionMemberByUserId = CrossUnionMgr.getUnionMemberByUserId(userId);
        if (unionMemberByUserId!=null){
            builder.setGrade(unionMemberByUserId.getAbilityRankGrade());
        }else {
            builder.setGrade(0);
        }
        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.S_PLAYER_MONTH_RANK_GRADE_SYNC_TO_GAME, builder));
    }

    public static CrossUnionMember createDeleteMember(CrossUserBaseInfo userBaseInfo, long serverId) {
        CrossUnionMember member;
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            member = CrossUnionMgr.getUnionMember("", userBaseInfo.getUserId());
            if (null == member) {
                member = new CrossUnionMember();
                member.setUnionUid("");
                member.setUserId(userBaseInfo.getUserId());
                member.setUserBaseInfo(userBaseInfo.getUserBaseInfo());
                member.setServerId(userBaseInfo.getUserBaseInfo().getServerId());
                member.setMonthAbilityRank(CrossGroupUserMonthAbilityRankMgr.getUserRank(member.getServerId(), member.getUserId()));

                member.setInsertOption();
                CrossUnionMgr.addMemberToDeleteMap(member);
            }
        }
        return member;
    }


    /**
     * 描述：增加需要同步的商会
     * 作者：zrq
     * 时间：2023/3/19
     * 参数：
     * <p>
     * 返回值：
     **/
    public static void addSyncMaxAbilityUnionSet(String unionUid) {
        synchronized (syncMaxAbilityUnionSet) {
            syncMaxAbilityUnionSet.add(unionUid);
        }
    }

    /**
     * 描述：定时器来同步商会
     * 作者：zrq
     * 时间：2023/3/19
     * 参数：
     * <p>
     * 返回值：
     **/
    public static void timerSyncMaxAbilityUnion() {
        Set<String> syncSet = new HashSet<>();
        synchronized (syncMaxAbilityUnionSet) {
            int count = 0;
            for (String unionUid : syncMaxAbilityUnionSet) {
                syncSet.add(unionUid);
                count++;
                if (count > 20) {
                    break;
                }
            }
            syncMaxAbilityUnionSet.removeAll(syncSet);
        }
        for (String unionId : syncSet) {
            CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionId);
            if (null != unionInfo && !unionInfo.isDelete()) {
                CrossUnionMgr.sendUnionChangeBroadcast(eUnionSyncType.Normal.getValue(), unionInfo, null, null, 0);
            }
        }
    }

    public static UnionRank pareUnionInfoToUnionRank(CrossUnionInfo unionInfo) {
        UnionRank unionRank = new UnionRank();
        unionRank.setUnionUid(unionInfo.getUnionUid());
        unionRank.setUnionBaseInfo(parseUnionBaseInfo(unionInfo));
        unionRank.setOriginalGradeAmountMap(unionInfo.getGradeAmountMap());
        unionRank.setGradeLimitAmountMap(unionInfo.getJoinGradeLimit());
        unionRank.setNowGradeAmountMap(getMemberRankGradeMap(unionInfo));
        return unionRank;
    }

    public static UnionValueRank pareUnionInfoToUnionValueRank(CrossUnionInfo unionInfo) {
        UnionValueRank unionRank = new UnionValueRank();
        unionRank.setUnionUid(unionInfo.getUnionUid());
        unionRank.setUnionBaseInfo(parseUnionBaseInfo(unionInfo));
        unionRank.setOriginalGradeAmountMap(unionInfo.getGradeAmountMap());
        unionRank.setGradeLimitAmountMap(unionInfo.getJoinGradeLimit());
        unionRank.setNowGradeAmountMap(getMemberRankGradeMap(unionInfo));
        unionRank.setValue(BigInteger.valueOf(unionInfo.getHonors()));
        return unionRank;
    }

    public static Map<Long, Integer> getMemberPositionMap(String unionUid) {
        Map<Long, Integer> map = new HashMap<>();
        Map<Long, CrossUnionMember> unionMemberMap = getUnionMemberMap(unionUid);
        if (unionMemberMap != null) {
            for (CrossUnionMember unionMember : unionMemberMap.values()) {
                map.put(unionMember.getUserId(), unionMember.getPosition());
            }
        }
        return map;
    }

    /**
     * 进会 退会 成员变化都要调用
     *
     * @param unionUid
     */
    public static void updateUnionTotalMaxAbility(String unionUid) {
        CrossUnionInfo unionInfo = getUnionInfo(unionUid);
        if (null == unionInfo) {
            return;
        }
        if (unionInfo.isDelete()) {
            return;
        }

        BigInteger totalAbility = BigInteger.ZERO;
        Map<Long, CrossUnionMember> memberMap = getUnionMemberMap(unionUid);
        for (CrossUnionMember member : memberMap.values()) {
            totalAbility = totalAbility.add(member.getHistoryMaxAbility());
        }
        unionInfo.setTotalMaxAbility(totalAbility);

    }
}
